@aws/nx-plugin 0.1.6 → 0.2.1
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/LICENSE-THIRD-PARTY +1554 -3241
- package/generators.json +1 -13
- package/package.json +14 -14
- package/src/cloudscape-website/app/README.md +84 -48
- package/src/cloudscape-website/app/__snapshots__/generator.spec.ts.snap +168 -233
- package/src/cloudscape-website/app/files/app/README.md.template +44 -0
- package/src/cloudscape-website/app/files/app/src/layouts/App/index.tsx.template +40 -43
- package/src/cloudscape-website/app/files/app/src/layouts/App/navitems.ts.template +3 -3
- package/src/cloudscape-website/app/files/app/src/layouts/Routes/index.tsx.template +4 -6
- package/src/cloudscape-website/app/files/app/src/main.tsx.template +7 -10
- package/src/cloudscape-website/app/files/app/src/pages/Home/index.tsx.template +0 -2
- package/src/cloudscape-website/app/files/common/constructs/src/app/static-websites/__websiteNameKebabCase__.ts.template +13 -0
- package/src/cloudscape-website/app/files/common/constructs/src/{__websiteNameKebabCase__ → core}/static-website.ts.template +79 -144
- package/src/cloudscape-website/app/generator.js +90 -74
- package/src/cloudscape-website/app/generator.js.map +1 -1
- package/src/cloudscape-website/app/schema.d.ts +3 -5
- package/src/cloudscape-website/app/schema.json +1 -24
- package/src/cloudscape-website/cognito-auth/README.md +53 -32
- package/src/cloudscape-website/cognito-auth/__snapshots__/generator.spec.ts.snap +162 -124
- package/src/cloudscape-website/cognito-auth/files/app/components/CognitoAuth/index.tsx.template +53 -39
- package/src/cloudscape-website/cognito-auth/files/common/constructs/src/core/user-identity.ts.template +168 -0
- package/src/cloudscape-website/cognito-auth/generator.js +130 -47
- package/src/cloudscape-website/cognito-auth/generator.js.map +1 -1
- package/src/cloudscape-website/cognito-auth/schema.d.ts +1 -0
- package/src/cloudscape-website/cognito-auth/schema.json +7 -1
- package/src/cloudscape-website/runtime-config/__snapshots__/generator.spec.ts.snap +20 -15
- package/src/cloudscape-website/runtime-config/files/app/components/RuntimeConfig/index.tsx.template +7 -10
- package/src/cloudscape-website/runtime-config/files/app/hooks/useRuntimeConfig.tsx.template +13 -0
- package/src/cloudscape-website/runtime-config/generator.js +4 -2
- package/src/cloudscape-website/runtime-config/generator.js.map +1 -1
- package/src/infra/app/README.md +71 -46
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +184 -305
- package/src/infra/app/files/app/README.md.template +76 -0
- package/src/infra/app/files/app/src/main.ts.template +18 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/aws-prototyping.guard +1282 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/cfn-nag.guard +6839 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/hipaa-security.guard +2807 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/nist-csf.guard +2585 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/pci-dss-3-2-1.guard +2236 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/wa-reliability-pillar.guard +885 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/wa-security-pillar.guard +2205 -0
- package/src/infra/app/files/common/constructs/src/core/cfn-guard.ts.template +63 -0
- package/src/infra/app/generator.js +36 -7
- package/src/infra/app/generator.js.map +1 -1
- package/src/infra/app/schema.d.ts +10 -1
- package/src/infra/app/schema.json +16 -8
- package/src/trpc/backend/README.md +102 -80
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +42 -19
- package/src/trpc/backend/files/backend/README.md.template +33 -0
- package/src/trpc/backend/files/common/constructs/src/app/trpc-apis/__apiNameKebabCase__.ts.template +18 -0
- package/src/trpc/backend/files/common/constructs/src/{__apiNameKebabCase__/index.ts.template → core/trpc-api.ts.template} +12 -16
- package/src/trpc/backend/files/schema/README.md.template +33 -0
- package/src/trpc/backend/generator.js +30 -44
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/backend/schema.d.ts +3 -1
- package/src/trpc/backend/schema.json +8 -13
- package/src/trpc/react/README.md +46 -66
- package/src/trpc/react/__snapshots__/generator.spec.ts.snap +104 -65
- package/src/trpc/react/files/src/components/TrpcClients/IsolatedTrpcProvider.tsx.template +75 -0
- package/src/trpc/react/files/src/components/TrpcClients/TrpcApis.tsx.template +1 -0
- package/src/trpc/react/files/src/components/TrpcClients/TrpcClientProviders.tsx.template +10 -0
- package/src/trpc/react/files/src/components/TrpcClients/index.tsx.template +5 -0
- package/src/trpc/react/files/src/hooks/useSigV4.tsx.template +38 -0
- package/src/trpc/react/files/src/hooks/use__apiNameClassName__.tsx.template +3 -0
- package/src/trpc/react/generator.js +124 -25
- package/src/trpc/react/generator.js.map +1 -1
- package/src/trpc/react/schema.json +2 -2
- package/src/ts/lib/__snapshots__/generator.spec.ts.snap +47 -93
- package/src/ts/lib/eslint.d.ts +1 -2
- package/src/ts/lib/eslint.js +62 -21
- package/src/ts/lib/eslint.js.map +1 -1
- package/src/ts/lib/files/README.md.template +33 -0
- package/src/ts/lib/generator.js +44 -5
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/schema.d.ts +1 -4
- package/src/ts/lib/schema.json +2 -21
- package/src/ts/lib/ts-project-utils.js +3 -18
- package/src/ts/lib/ts-project-utils.js.map +1 -1
- package/src/ts/lib/vitest.js +12 -0
- package/src/ts/lib/vitest.js.map +1 -1
- package/src/utils/ast.d.ts +13 -0
- package/src/utils/ast.js +102 -0
- package/src/utils/ast.js.map +1 -0
- package/src/utils/files/common/constructs/src/app/index.ts.template +0 -0
- package/src/utils/files/common/constructs/src/{runtime-config → core}/runtime-config.ts.template +3 -5
- package/src/utils/files/common/constructs/src/index.ts.template +2 -1
- package/src/utils/files/common/readme/README.md.template +33 -0
- package/src/utils/files/common/types/src/runtime-config.ts.template +2 -13
- package/src/utils/format.d.ts +1 -1
- package/src/utils/format.js +2 -2
- package/src/utils/format.js.map +1 -1
- package/src/utils/names.d.ts +2 -0
- package/src/utils/names.js +27 -0
- package/src/utils/names.js.map +1 -0
- package/src/utils/npm-scope.js.map +1 -1
- package/src/utils/paths.js.map +1 -1
- package/src/utils/shared-constructs.js +37 -4
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/test.d.ts +2 -0
- package/src/utils/test.js +19 -0
- package/src/utils/test.js.map +1 -0
- package/src/utils/versions.d.ts +15 -9
- package/src/utils/versions.js +14 -8
- package/src/utils/versions.js.map +1 -1
- package/src/cloudscape-website/app/files/common/constructs/src/__websiteNameKebabCase__/cloudfront-web-acl.ts.template +0 -317
- package/src/cloudscape-website/app/files/common/constructs/src/__websiteNameKebabCase__/index.ts.template +0 -4
- package/src/cloudscape-website/app/files/common/constructs/src/__websiteNameKebabCase__/webacl_event_handler/index.ts.template +0 -301
- package/src/cloudscape-website/cognito-auth/files/common/constructs/src/identity/index.ts.template +0 -4
- package/src/cloudscape-website/cognito-auth/files/common/constructs/src/identity/user-identity.ts.template +0 -66
- package/src/cloudscape-website/cognito-auth/files/common/constructs/src/identity/userpool-with-mfa.ts.template +0 -70
- package/src/gitlab/generator.d.ts +0 -8
- package/src/gitlab/generator.js +0 -16
- package/src/gitlab/generator.js.map +0 -1
- package/src/gitlab/schema.d.ts +0 -9
- package/src/gitlab/schema.json +0 -52
- package/src/infra/app/files/src/main.ts.template +0 -37
- package/src/trpc/react/files/src/components/TRPCClientProvider/index.tsx.template +0 -34
- package/src/trpc/react/files/src/hooks/useTrpc.tsx.template +0 -5
- package/src/ts/cjs-to-esm/generator.d.ts +0 -12
- package/src/ts/cjs-to-esm/generator.js +0 -189
- package/src/ts/cjs-to-esm/generator.js.map +0 -1
- package/src/ts/cjs-to-esm/schema.d.ts +0 -9
- package/src/ts/cjs-to-esm/schema.json +0 -28
- /package/src/infra/app/files/{cdk.json → app/cdk.json} +0 -0
- /package/src/infra/app/files/{src → app/src}/stacks/application-stack.ts.template +0 -0
- /package/src/utils/files/common/constructs/src/{runtime-config → core}/index.ts.template +0 -0
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`cognito-auth generator > should generate files > cognito-auth-component 1`] = `
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import Config from '../../config';
|
|
9
|
-
import { RuntimeConfigContext } from '../RuntimeConfig';
|
|
4
|
+
"import React, { PropsWithChildren, useEffect } from 'react';
|
|
5
|
+
import { AuthProvider, AuthProviderProps, useAuth } from 'react-oidc-context';
|
|
6
|
+
import { Alert, Spinner } from '@cloudscape-design/components';
|
|
7
|
+
import { useRuntimeConfig } from '../../hooks/useRuntimeConfig';
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
10
|
* Sets up the Cognito auth.
|
|
@@ -14,104 +12,119 @@ import { RuntimeConfigContext } from '../RuntimeConfig';
|
|
|
14
12
|
* This assumes a runtime-config.json file is present at '/'. In order for Auth to be set up automatically,
|
|
15
13
|
* the runtime-config.json must have the cognitoProps set.
|
|
16
14
|
*/
|
|
17
|
-
const CognitoAuth: React.FC<
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
header=
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
displayName: 'Last name',
|
|
41
|
-
name: 'family_name',
|
|
42
|
-
required: true,
|
|
43
|
-
},
|
|
44
|
-
]}
|
|
45
|
-
>
|
|
46
|
-
{children}
|
|
47
|
-
</NorthstarCognitoAuth>
|
|
48
|
-
) : (
|
|
49
|
-
<></>
|
|
15
|
+
const CognitoAuth: React.FC<PropsWithChildren> = ({ children }) => {
|
|
16
|
+
const { cognitoProps } = useRuntimeConfig();
|
|
17
|
+
|
|
18
|
+
if (!cognitoProps) {
|
|
19
|
+
return (
|
|
20
|
+
<Alert type="error" header="Runtime config configuration error">
|
|
21
|
+
The cognitoProps have not been configured in the runtime-config.json.
|
|
22
|
+
</Alert>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const cognitoAuthConfig: AuthProviderProps = {
|
|
27
|
+
authority: \`https://cognito-idp.\${cognitoProps.region}.amazonaws.com/\${cognitoProps.userPoolId}\`,
|
|
28
|
+
client_id: cognitoProps.userPoolWebClientId,
|
|
29
|
+
redirect_uri: window.location.origin,
|
|
30
|
+
response_type: 'code',
|
|
31
|
+
scope: 'email openid profile',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<AuthProvider {...cognitoAuthConfig}>
|
|
36
|
+
<CognitoAuthInternal>{children}</CognitoAuthInternal>
|
|
37
|
+
</AuthProvider>
|
|
50
38
|
);
|
|
51
39
|
};
|
|
52
40
|
|
|
41
|
+
const CognitoAuthInternal: React.FC<PropsWithChildren> = ({ children }) => {
|
|
42
|
+
const auth = useAuth();
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!auth.isAuthenticated && !auth.isLoading) {
|
|
46
|
+
auth.signinRedirect();
|
|
47
|
+
}
|
|
48
|
+
}, [auth]);
|
|
49
|
+
|
|
50
|
+
if (auth.isAuthenticated) {
|
|
51
|
+
return children;
|
|
52
|
+
} else if (auth.error) {
|
|
53
|
+
return (
|
|
54
|
+
<Alert type="error" header="Configuration error">
|
|
55
|
+
Error contacting Cognito. Please check your runtime-config.json is
|
|
56
|
+
configured with the correct endpoints.
|
|
57
|
+
</Alert>
|
|
58
|
+
);
|
|
59
|
+
} else {
|
|
60
|
+
return <Spinner />;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
53
64
|
export default CognitoAuth;
|
|
54
65
|
"
|
|
55
66
|
`;
|
|
56
67
|
|
|
57
68
|
exports[`cognito-auth generator > should generate files > identity-index 1`] = `
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
export * from './user-identity.js';
|
|
61
|
-
export * from './userpool-with-mfa.js';
|
|
69
|
+
"export * from './user-identity.js';
|
|
70
|
+
export * from './runtime-config.js';
|
|
62
71
|
"
|
|
63
72
|
`;
|
|
64
73
|
|
|
65
74
|
exports[`cognito-auth generator > should generate files > user-identity 1`] = `
|
|
66
|
-
"
|
|
67
|
-
SPDX-License-Identifier: Apache-2.0 */
|
|
68
|
-
import {
|
|
75
|
+
"import {
|
|
69
76
|
IdentityPool,
|
|
70
77
|
UserPoolAuthenticationProvider,
|
|
71
78
|
} from '@aws-cdk/aws-cognito-identitypool-alpha';
|
|
72
|
-
import { CfnOutput, Stack } from 'aws-cdk-lib';
|
|
73
|
-
import {
|
|
79
|
+
import { CfnOutput, Duration, Lazy, Stack } from 'aws-cdk-lib';
|
|
80
|
+
import {
|
|
81
|
+
AccountRecovery,
|
|
82
|
+
CfnManagedLoginBranding,
|
|
83
|
+
CfnUserPoolDomain,
|
|
84
|
+
FeaturePlan,
|
|
85
|
+
Mfa,
|
|
86
|
+
OAuthScope,
|
|
87
|
+
UserPool,
|
|
88
|
+
UserPoolClient,
|
|
89
|
+
} from 'aws-cdk-lib/aws-cognito';
|
|
74
90
|
import { Construct } from 'constructs';
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
91
|
+
import { RuntimeConfig } from './runtime-config.js';
|
|
92
|
+
import { Distribution } from 'aws-cdk-lib/aws-cloudfront';
|
|
77
93
|
|
|
78
94
|
const WEB_CLIENT_ID = 'WebClient';
|
|
79
|
-
|
|
80
95
|
/**
|
|
81
96
|
* Creates a UserPool and Identity Pool with sane defaults configured intended for usage from a web client.
|
|
82
97
|
*/
|
|
83
98
|
export class UserIdentity extends Construct {
|
|
99
|
+
public readonly region: string;
|
|
84
100
|
public readonly identityPool: IdentityPool;
|
|
85
101
|
public readonly userPool: UserPool;
|
|
86
102
|
public readonly userPoolClient: UserPoolClient;
|
|
103
|
+
public readonly userPoolDomain: CfnUserPoolDomain;
|
|
87
104
|
|
|
88
105
|
constructor(scope: Construct, id: string) {
|
|
89
106
|
super(scope, id);
|
|
90
107
|
|
|
91
|
-
|
|
92
|
-
this.userPool =
|
|
93
|
-
|
|
94
|
-
this.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
) as UserPoolClient | undefined;
|
|
99
|
-
|
|
100
|
-
this.userPoolClient =
|
|
101
|
-
existingClient ??
|
|
102
|
-
this.userPool.addClient(WEB_CLIENT_ID, {
|
|
103
|
-
authFlows: {
|
|
104
|
-
userPassword: true,
|
|
105
|
-
userSrp: true,
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
this.identityPool.addUserPoolAuthentication(
|
|
110
|
-
new UserPoolAuthenticationProvider({
|
|
111
|
-
userPool: this.userPool,
|
|
112
|
-
userPoolClient: this.userPoolClient,
|
|
113
|
-
})
|
|
108
|
+
this.region = Stack.of(this).region;
|
|
109
|
+
this.userPool = this.createUserPool();
|
|
110
|
+
this.userPoolDomain = this.createUserPoolDomain(this.userPool);
|
|
111
|
+
this.userPoolClient = this.createUserPoolClient(this.userPool);
|
|
112
|
+
this.identityPool = this.createIdentityPool(
|
|
113
|
+
this.userPool,
|
|
114
|
+
this.userPoolClient,
|
|
114
115
|
);
|
|
116
|
+
this.createManagedLoginBranding(
|
|
117
|
+
this.userPool,
|
|
118
|
+
this.userPoolClient,
|
|
119
|
+
this.userPoolDomain,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
RuntimeConfig.ensure(this).config.cognitoProps = {
|
|
123
|
+
region: Stack.of(this).region,
|
|
124
|
+
identityPoolId: this.identityPool.identityPoolId,
|
|
125
|
+
userPoolId: this.userPool.userPoolId,
|
|
126
|
+
userPoolWebClientId: this.userPoolClient.userPoolClientId,
|
|
127
|
+
};
|
|
115
128
|
|
|
116
129
|
new CfnOutput(this, \`\${id}-UserPoolId\`, {
|
|
117
130
|
value: this.userPool.userPoolId,
|
|
@@ -120,37 +133,10 @@ export class UserIdentity extends Construct {
|
|
|
120
133
|
new CfnOutput(this, \`\${id}-IdentityPoolId\`, {
|
|
121
134
|
value: this.identityPool.identityPoolId,
|
|
122
135
|
});
|
|
123
|
-
|
|
124
|
-
RuntimeConfig.ensure(this).config.cognitoProps = {
|
|
125
|
-
region: Stack.of(this).region,
|
|
126
|
-
identityPoolId: this.identityPool.identityPoolId,
|
|
127
|
-
userPoolId: this.userPool?.userPoolId,
|
|
128
|
-
userPoolWebClientId: this.userPoolClient?.userPoolClientId,
|
|
129
|
-
};
|
|
130
136
|
}
|
|
131
|
-
}
|
|
132
|
-
"
|
|
133
|
-
`;
|
|
134
137
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
SPDX-License-Identifier: Apache-2.0 */
|
|
138
|
-
import { PDKNag } from '@aws/pdk/pdk-nag';
|
|
139
|
-
import { Duration, Stack } from 'aws-cdk-lib';
|
|
140
|
-
import {
|
|
141
|
-
AccountRecovery,
|
|
142
|
-
AdvancedSecurityMode,
|
|
143
|
-
Mfa,
|
|
144
|
-
UserPool,
|
|
145
|
-
} from 'aws-cdk-lib/aws-cognito';
|
|
146
|
-
import { Construct } from 'constructs';
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Configures a UserPool with MFA across SMS/TOTP using sane defaults.
|
|
150
|
-
*/
|
|
151
|
-
export class UserPoolWithMfa extends UserPool {
|
|
152
|
-
constructor(scope: Construct, id: string) {
|
|
153
|
-
super(scope, id, {
|
|
138
|
+
private createUserPool = () =>
|
|
139
|
+
new UserPool(this, 'UserPool', {
|
|
154
140
|
deletionProtection: true,
|
|
155
141
|
passwordPolicy: {
|
|
156
142
|
minLength: 8,
|
|
@@ -161,9 +147,9 @@ export class UserPoolWithMfa extends UserPool {
|
|
|
161
147
|
tempPasswordValidity: Duration.days(3),
|
|
162
148
|
},
|
|
163
149
|
mfa: Mfa.REQUIRED,
|
|
150
|
+
featurePlan: FeaturePlan.ESSENTIALS,
|
|
164
151
|
mfaSecondFactor: { sms: true, otp: true },
|
|
165
152
|
signInCaseSensitive: false,
|
|
166
|
-
advancedSecurityMode: AdvancedSecurityMode.ENFORCED,
|
|
167
153
|
signInAliases: { username: true, email: true },
|
|
168
154
|
accountRecovery: AccountRecovery.EMAIL_ONLY,
|
|
169
155
|
selfSignUpEnabled: true,
|
|
@@ -183,25 +169,76 @@ export class UserPoolWithMfa extends UserPool {
|
|
|
183
169
|
},
|
|
184
170
|
});
|
|
185
171
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
172
|
+
private createUserPoolDomain = (userPool: UserPool) =>
|
|
173
|
+
new CfnUserPoolDomain(this, 'UserPoolDomain', {
|
|
174
|
+
domain: \`test-\${Stack.of(this).account}\`,
|
|
175
|
+
userPoolId: userPool.userPoolId,
|
|
176
|
+
managedLoginVersion: 2,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
private createUserPoolClient = (userPool: UserPool) => {
|
|
180
|
+
const lazilyComputedCallbackUrls = Lazy.list({
|
|
181
|
+
produce: () =>
|
|
182
|
+
[
|
|
183
|
+
'http://localhost:4200',
|
|
184
|
+
\`https://\${Stack.of(this).region}.console.aws.amazon.com\`,
|
|
185
|
+
].concat(
|
|
186
|
+
this.findCloudFrontDistributions().map(
|
|
187
|
+
(d) => \`https://\${d.domainName}\`,
|
|
188
|
+
),
|
|
189
|
+
),
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
return userPool.addClient(WEB_CLIENT_ID, {
|
|
193
|
+
authFlows: {
|
|
194
|
+
userPassword: true,
|
|
195
|
+
userSrp: true,
|
|
196
|
+
user: true,
|
|
197
|
+
},
|
|
198
|
+
oAuth: {
|
|
199
|
+
flows: {
|
|
200
|
+
authorizationCodeGrant: true,
|
|
201
|
+
},
|
|
202
|
+
scopes: [OAuthScope.EMAIL, OAuthScope.OPENID, OAuthScope.PROFILE],
|
|
203
|
+
callbackUrls: lazilyComputedCallbackUrls,
|
|
204
|
+
logoutUrls: lazilyComputedCallbackUrls,
|
|
205
|
+
},
|
|
206
|
+
preventUserExistenceErrors: true,
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
private createIdentityPool = (
|
|
211
|
+
userPool: UserPool,
|
|
212
|
+
userPoolClient: UserPoolClient,
|
|
213
|
+
) => {
|
|
214
|
+
const identityPool = new IdentityPool(this, 'IdentityPool');
|
|
215
|
+
|
|
216
|
+
identityPool.addUserPoolAuthentication(
|
|
217
|
+
new UserPoolAuthenticationProvider({
|
|
218
|
+
userPool,
|
|
219
|
+
userPoolClient,
|
|
220
|
+
}),
|
|
203
221
|
);
|
|
204
|
-
|
|
222
|
+
|
|
223
|
+
return identityPool;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
private createManagedLoginBranding = (
|
|
227
|
+
userPool: UserPool,
|
|
228
|
+
userPoolClient: UserPoolClient,
|
|
229
|
+
userPoolDomain: CfnUserPoolDomain,
|
|
230
|
+
) => {
|
|
231
|
+
new CfnManagedLoginBranding(this, 'ManagedLoginBranding', {
|
|
232
|
+
userPoolId: userPool.userPoolId,
|
|
233
|
+
clientId: userPoolClient.userPoolClientId,
|
|
234
|
+
useCognitoProvidedValues: true,
|
|
235
|
+
}).node.addDependency(userPoolClient, userPool, userPoolDomain);
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
private findCloudFrontDistributions = (): Distribution[] =>
|
|
239
|
+
Stack.of(this)
|
|
240
|
+
.node.findAll()
|
|
241
|
+
.filter((child) => child instanceof Distribution);
|
|
205
242
|
}
|
|
206
243
|
"
|
|
207
244
|
`;
|
|
@@ -228,6 +265,7 @@ export function App() {
|
|
|
228
265
|
`;
|
|
229
266
|
|
|
230
267
|
exports[`cognito-auth generator > should update shared constructs index.ts > common/constructs-index 1`] = `
|
|
231
|
-
"export * from './identity
|
|
232
|
-
export * from './runtime-config
|
|
268
|
+
"export * from './user-identity.js';
|
|
269
|
+
export * from './runtime-config.js';
|
|
270
|
+
"
|
|
233
271
|
`;
|
package/src/cloudscape-website/cognito-auth/files/app/components/CognitoAuth/index.tsx.template
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import Config from '../../config';
|
|
6
|
-
import { RuntimeConfigContext } from '../RuntimeConfig';
|
|
1
|
+
import React, { PropsWithChildren, useEffect } from 'react';
|
|
2
|
+
import { AuthProvider, AuthProviderProps, useAuth } from 'react-oidc-context';
|
|
3
|
+
import { Alert, Spinner } from '@cloudscape-design/components';
|
|
4
|
+
import { useRuntimeConfig } from '../../hooks/useRuntimeConfig';
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* Sets up the Cognito auth.
|
|
@@ -11,40 +9,56 @@ import { RuntimeConfigContext } from '../RuntimeConfig';
|
|
|
11
9
|
* This assumes a runtime-config.json file is present at '/'. In order for Auth to be set up automatically,
|
|
12
10
|
* the runtime-config.json must have the cognitoProps set.
|
|
13
11
|
*/
|
|
14
|
-
const CognitoAuth: React.FC<
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
},
|
|
41
|
-
]}
|
|
42
|
-
>
|
|
43
|
-
{children}
|
|
44
|
-
</NorthstarCognitoAuth>
|
|
45
|
-
) : (
|
|
46
|
-
<></>
|
|
12
|
+
const CognitoAuth: React.FC<PropsWithChildren> = ({ children }) => {
|
|
13
|
+
const { cognitoProps } = useRuntimeConfig();
|
|
14
|
+
|
|
15
|
+
if (!cognitoProps) {
|
|
16
|
+
return (
|
|
17
|
+
<Alert
|
|
18
|
+
type="error"
|
|
19
|
+
header="Runtime config configuration error"
|
|
20
|
+
>
|
|
21
|
+
The cognitoProps have not been configured in the runtime-config.json.
|
|
22
|
+
</Alert>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const cognitoAuthConfig: AuthProviderProps = {
|
|
27
|
+
authority: `https://cognito-idp.${cognitoProps.region}.amazonaws.com/${cognitoProps.userPoolId}`,
|
|
28
|
+
client_id: cognitoProps.userPoolWebClientId,
|
|
29
|
+
redirect_uri: window.location.origin,
|
|
30
|
+
response_type: 'code',
|
|
31
|
+
scope: 'email openid profile',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<AuthProvider {...cognitoAuthConfig}>
|
|
36
|
+
<CognitoAuthInternal>{children}</CognitoAuthInternal>
|
|
37
|
+
</AuthProvider>
|
|
47
38
|
);
|
|
48
39
|
};
|
|
49
40
|
|
|
41
|
+
const CognitoAuthInternal: React.FC<PropsWithChildren> = ({ children }) => {
|
|
42
|
+
const auth = useAuth();
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!auth.isAuthenticated && !auth.isLoading) {
|
|
46
|
+
auth.signinRedirect();
|
|
47
|
+
}
|
|
48
|
+
}, [auth])
|
|
49
|
+
|
|
50
|
+
if (auth.isAuthenticated) {
|
|
51
|
+
return children;
|
|
52
|
+
} else if (auth.error) {
|
|
53
|
+
return (
|
|
54
|
+
<Alert type="error" header="Configuration error">
|
|
55
|
+
Error contacting Cognito. Please check your runtime-config.json is
|
|
56
|
+
configured with the correct endpoints.
|
|
57
|
+
</Alert>
|
|
58
|
+
);
|
|
59
|
+
} else {
|
|
60
|
+
return <Spinner />;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
50
64
|
export default CognitoAuth;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IdentityPool,
|
|
3
|
+
UserPoolAuthenticationProvider,
|
|
4
|
+
} from '@aws-cdk/aws-cognito-identitypool-alpha';
|
|
5
|
+
import { CfnOutput, Duration, Lazy, Stack } from 'aws-cdk-lib';
|
|
6
|
+
import {
|
|
7
|
+
AccountRecovery,
|
|
8
|
+
CfnManagedLoginBranding,
|
|
9
|
+
CfnUserPoolDomain,
|
|
10
|
+
FeaturePlan,
|
|
11
|
+
Mfa,
|
|
12
|
+
OAuthScope,
|
|
13
|
+
UserPool,
|
|
14
|
+
UserPoolClient,
|
|
15
|
+
} from 'aws-cdk-lib/aws-cognito';
|
|
16
|
+
import { Construct } from 'constructs';
|
|
17
|
+
import { RuntimeConfig } from './runtime-config.js';
|
|
18
|
+
import { Distribution } from 'aws-cdk-lib/aws-cloudfront';
|
|
19
|
+
|
|
20
|
+
const WEB_CLIENT_ID = 'WebClient';
|
|
21
|
+
/**
|
|
22
|
+
* Creates a UserPool and Identity Pool with sane defaults configured intended for usage from a web client.
|
|
23
|
+
*/
|
|
24
|
+
export class UserIdentity extends Construct {
|
|
25
|
+
public readonly region: string;
|
|
26
|
+
public readonly identityPool: IdentityPool;
|
|
27
|
+
public readonly userPool: UserPool;
|
|
28
|
+
public readonly userPoolClient: UserPoolClient;
|
|
29
|
+
public readonly userPoolDomain: CfnUserPoolDomain;
|
|
30
|
+
|
|
31
|
+
constructor(scope: Construct, id: string) {
|
|
32
|
+
super(scope, id);
|
|
33
|
+
|
|
34
|
+
this.region = Stack.of(this).region;
|
|
35
|
+
this.userPool = this.createUserPool();
|
|
36
|
+
this.userPoolDomain = this.createUserPoolDomain(this.userPool);
|
|
37
|
+
this.userPoolClient = this.createUserPoolClient(this.userPool);
|
|
38
|
+
this.identityPool = this.createIdentityPool(
|
|
39
|
+
this.userPool,
|
|
40
|
+
this.userPoolClient
|
|
41
|
+
);
|
|
42
|
+
this.createManagedLoginBranding(
|
|
43
|
+
this.userPool,
|
|
44
|
+
this.userPoolClient,
|
|
45
|
+
this.userPoolDomain
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
RuntimeConfig.ensure(this).config.cognitoProps = {
|
|
49
|
+
region: Stack.of(this).region,
|
|
50
|
+
identityPoolId: this.identityPool.identityPoolId,
|
|
51
|
+
userPoolId: this.userPool.userPoolId,
|
|
52
|
+
userPoolWebClientId: this.userPoolClient.userPoolClientId,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
new CfnOutput(this, `${id}-UserPoolId`, {
|
|
56
|
+
value: this.userPool.userPoolId,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
new CfnOutput(this, `${id}-IdentityPoolId`, {
|
|
60
|
+
value: this.identityPool.identityPoolId,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private createUserPool = () =>
|
|
65
|
+
new UserPool(this, 'UserPool', {
|
|
66
|
+
deletionProtection: true,
|
|
67
|
+
passwordPolicy: {
|
|
68
|
+
minLength: 8,
|
|
69
|
+
requireLowercase: true,
|
|
70
|
+
requireUppercase: true,
|
|
71
|
+
requireDigits: true,
|
|
72
|
+
requireSymbols: true,
|
|
73
|
+
tempPasswordValidity: Duration.days(3),
|
|
74
|
+
},
|
|
75
|
+
mfa: Mfa.REQUIRED,
|
|
76
|
+
featurePlan: FeaturePlan.ESSENTIALS,
|
|
77
|
+
mfaSecondFactor: { sms: true, otp: true },
|
|
78
|
+
signInCaseSensitive: false,
|
|
79
|
+
signInAliases: { username: true, email: true },
|
|
80
|
+
accountRecovery: AccountRecovery.EMAIL_ONLY,
|
|
81
|
+
selfSignUpEnabled: <%= allowSignup %>,
|
|
82
|
+
standardAttributes: {
|
|
83
|
+
phoneNumber: { required: false },
|
|
84
|
+
email: { required: true },
|
|
85
|
+
givenName: { required: true },
|
|
86
|
+
familyName: { required: true },
|
|
87
|
+
},
|
|
88
|
+
autoVerify: {
|
|
89
|
+
email: true,
|
|
90
|
+
phone: true,
|
|
91
|
+
},
|
|
92
|
+
keepOriginal: {
|
|
93
|
+
email: true,
|
|
94
|
+
phone: true,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
private createUserPoolDomain = (userPool: UserPool) =>
|
|
99
|
+
new CfnUserPoolDomain(this, 'UserPoolDomain', {
|
|
100
|
+
domain: `<%= cognitoDomain %>-${Stack.of(this).account}`,
|
|
101
|
+
userPoolId: userPool.userPoolId,
|
|
102
|
+
managedLoginVersion: 2,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
private createUserPoolClient = (userPool: UserPool) => {
|
|
106
|
+
const lazilyComputedCallbackUrls = Lazy.list({
|
|
107
|
+
produce: () =>
|
|
108
|
+
[
|
|
109
|
+
'http://localhost:4200',
|
|
110
|
+
`https://${Stack.of(this).region}.console.aws.amazon.com`,
|
|
111
|
+
].concat(
|
|
112
|
+
this.findCloudFrontDistributions().map(
|
|
113
|
+
(d) => `https://${d.domainName}`
|
|
114
|
+
)
|
|
115
|
+
),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return userPool.addClient(WEB_CLIENT_ID, {
|
|
119
|
+
authFlows: {
|
|
120
|
+
userPassword: true,
|
|
121
|
+
userSrp: true,
|
|
122
|
+
user: true,
|
|
123
|
+
},
|
|
124
|
+
oAuth: {
|
|
125
|
+
flows: {
|
|
126
|
+
authorizationCodeGrant: true,
|
|
127
|
+
},
|
|
128
|
+
scopes: [OAuthScope.EMAIL, OAuthScope.OPENID, OAuthScope.PROFILE],
|
|
129
|
+
callbackUrls: lazilyComputedCallbackUrls,
|
|
130
|
+
logoutUrls: lazilyComputedCallbackUrls,
|
|
131
|
+
},
|
|
132
|
+
preventUserExistenceErrors: true,
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
private createIdentityPool = (
|
|
137
|
+
userPool: UserPool,
|
|
138
|
+
userPoolClient: UserPoolClient
|
|
139
|
+
) => {
|
|
140
|
+
const identityPool = new IdentityPool(this, 'IdentityPool');
|
|
141
|
+
|
|
142
|
+
identityPool.addUserPoolAuthentication(
|
|
143
|
+
new UserPoolAuthenticationProvider({
|
|
144
|
+
userPool,
|
|
145
|
+
userPoolClient,
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
return identityPool;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
private createManagedLoginBranding = (
|
|
153
|
+
userPool: UserPool,
|
|
154
|
+
userPoolClient: UserPoolClient,
|
|
155
|
+
userPoolDomain: CfnUserPoolDomain
|
|
156
|
+
) => {
|
|
157
|
+
new CfnManagedLoginBranding(this, 'ManagedLoginBranding', {
|
|
158
|
+
userPoolId: userPool.userPoolId,
|
|
159
|
+
clientId: userPoolClient.userPoolClientId,
|
|
160
|
+
useCognitoProvidedValues: true,
|
|
161
|
+
}).node.addDependency(userPoolClient, userPool, userPoolDomain);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
private findCloudFrontDistributions = (): Distribution[] =>
|
|
165
|
+
Stack.of(this)
|
|
166
|
+
.node.findAll()
|
|
167
|
+
.filter((child) => child instanceof Distribution);
|
|
168
|
+
}
|