@aws/nx-plugin 0.1.6 → 0.2.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/LICENSE-THIRD-PARTY +114 -244
- package/generators.json +1 -7
- package/package.json +1 -1
- package/src/cloudscape-website/app/README.md +84 -48
- package/src/cloudscape-website/app/__snapshots__/generator.spec.ts.snap +157 -218
- 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 +74 -144
- package/src/cloudscape-website/app/generator.js +74 -64
- package/src/cloudscape-website/app/generator.js.map +1 -1
- package/src/cloudscape-website/app/schema.d.ts +3 -4
- 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 +161 -125
- 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 +129 -46
- 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 +15 -17
- 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 +3 -1
- 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 +114 -252
- 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 +17 -3
- 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 +37 -17
- 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 +29 -43
- 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 +123 -24
- package/src/trpc/react/generator.js.map +1 -1
- package/src/trpc/react/schema.json +2 -2
- package/src/ts/cjs-to-esm/generator.js.map +1 -1
- package/src/ts/lib/eslint.d.ts +1 -1
- package/src/ts/lib/eslint.js +59 -11
- 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 +11 -4
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/schema.d.ts +1 -3
- package/src/ts/lib/schema.json +2 -15
- package/src/ts/lib/ts-project-utils.js.map +1 -1
- package/src/ts/lib/vitest.js +14 -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 +1 -13
- 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/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/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,105 +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';
|
|
62
|
-
"
|
|
69
|
+
"export * from "./user-identity.js";
|
|
70
|
+
export * from './runtime-config.js';"
|
|
63
71
|
`;
|
|
64
72
|
|
|
65
73
|
exports[`cognito-auth generator > should generate files > user-identity 1`] = `
|
|
66
|
-
"
|
|
67
|
-
SPDX-License-Identifier: Apache-2.0 */
|
|
68
|
-
import {
|
|
74
|
+
"import {
|
|
69
75
|
IdentityPool,
|
|
70
76
|
UserPoolAuthenticationProvider,
|
|
71
77
|
} from '@aws-cdk/aws-cognito-identitypool-alpha';
|
|
72
|
-
import { CfnOutput, Stack } from 'aws-cdk-lib';
|
|
73
|
-
import {
|
|
78
|
+
import { CfnOutput, Duration, Lazy, Stack } from 'aws-cdk-lib';
|
|
79
|
+
import {
|
|
80
|
+
AccountRecovery,
|
|
81
|
+
CfnManagedLoginBranding,
|
|
82
|
+
CfnUserPoolDomain,
|
|
83
|
+
FeaturePlan,
|
|
84
|
+
Mfa,
|
|
85
|
+
OAuthScope,
|
|
86
|
+
UserPool,
|
|
87
|
+
UserPoolClient,
|
|
88
|
+
} from 'aws-cdk-lib/aws-cognito';
|
|
74
89
|
import { Construct } from 'constructs';
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
90
|
+
import { RuntimeConfig } from './runtime-config.js';
|
|
91
|
+
import { Distribution } from 'aws-cdk-lib/aws-cloudfront';
|
|
77
92
|
|
|
78
93
|
const WEB_CLIENT_ID = 'WebClient';
|
|
79
|
-
|
|
80
94
|
/**
|
|
81
95
|
* Creates a UserPool and Identity Pool with sane defaults configured intended for usage from a web client.
|
|
82
96
|
*/
|
|
83
97
|
export class UserIdentity extends Construct {
|
|
98
|
+
public readonly region: string;
|
|
84
99
|
public readonly identityPool: IdentityPool;
|
|
85
100
|
public readonly userPool: UserPool;
|
|
86
101
|
public readonly userPoolClient: UserPoolClient;
|
|
102
|
+
public readonly userPoolDomain: CfnUserPoolDomain;
|
|
87
103
|
|
|
88
104
|
constructor(scope: Construct, id: string) {
|
|
89
105
|
super(scope, id);
|
|
90
106
|
|
|
91
|
-
|
|
92
|
-
this.userPool =
|
|
93
|
-
|
|
94
|
-
this.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
this.
|
|
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
|
-
})
|
|
107
|
+
this.region = Stack.of(this).region;
|
|
108
|
+
this.userPool = this.createUserPool();
|
|
109
|
+
this.userPoolDomain = this.createUserPoolDomain(this.userPool);
|
|
110
|
+
this.userPoolClient = this.createUserPoolClient(this.userPool);
|
|
111
|
+
this.identityPool = this.createIdentityPool(
|
|
112
|
+
this.userPool,
|
|
113
|
+
this.userPoolClient
|
|
114
|
+
);
|
|
115
|
+
this.createManagedLoginBranding(
|
|
116
|
+
this.userPool,
|
|
117
|
+
this.userPoolClient,
|
|
118
|
+
this.userPoolDomain
|
|
114
119
|
);
|
|
115
120
|
|
|
121
|
+
RuntimeConfig.ensure(this).config.cognitoProps = {
|
|
122
|
+
region: Stack.of(this).region,
|
|
123
|
+
identityPoolId: this.identityPool.identityPoolId,
|
|
124
|
+
userPoolId: this.userPool.userPoolId,
|
|
125
|
+
userPoolWebClientId: this.userPoolClient.userPoolClientId,
|
|
126
|
+
};
|
|
127
|
+
|
|
116
128
|
new CfnOutput(this, \`\${id}-UserPoolId\`, {
|
|
117
129
|
value: this.userPool.userPoolId,
|
|
118
130
|
});
|
|
@@ -120,37 +132,10 @@ export class UserIdentity extends Construct {
|
|
|
120
132
|
new CfnOutput(this, \`\${id}-IdentityPoolId\`, {
|
|
121
133
|
value: this.identityPool.identityPoolId,
|
|
122
134
|
});
|
|
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
135
|
}
|
|
131
|
-
}
|
|
132
|
-
"
|
|
133
|
-
`;
|
|
134
136
|
|
|
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, {
|
|
137
|
+
private createUserPool = () =>
|
|
138
|
+
new UserPool(this, 'UserPool', {
|
|
154
139
|
deletionProtection: true,
|
|
155
140
|
passwordPolicy: {
|
|
156
141
|
minLength: 8,
|
|
@@ -161,9 +146,9 @@ export class UserPoolWithMfa extends UserPool {
|
|
|
161
146
|
tempPasswordValidity: Duration.days(3),
|
|
162
147
|
},
|
|
163
148
|
mfa: Mfa.REQUIRED,
|
|
149
|
+
featurePlan: FeaturePlan.ESSENTIALS,
|
|
164
150
|
mfaSecondFactor: { sms: true, otp: true },
|
|
165
151
|
signInCaseSensitive: false,
|
|
166
|
-
advancedSecurityMode: AdvancedSecurityMode.ENFORCED,
|
|
167
152
|
signInAliases: { username: true, email: true },
|
|
168
153
|
accountRecovery: AccountRecovery.EMAIL_ONLY,
|
|
169
154
|
selfSignUpEnabled: true,
|
|
@@ -183,25 +168,76 @@ export class UserPoolWithMfa extends UserPool {
|
|
|
183
168
|
},
|
|
184
169
|
});
|
|
185
170
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
171
|
+
private createUserPoolDomain = (userPool: UserPool) =>
|
|
172
|
+
new CfnUserPoolDomain(this, 'UserPoolDomain', {
|
|
173
|
+
domain: \`test-\${Stack.of(this).account}\`,
|
|
174
|
+
userPoolId: userPool.userPoolId,
|
|
175
|
+
managedLoginVersion: 2,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
private createUserPoolClient = (userPool: UserPool) => {
|
|
179
|
+
const lazilyComputedCallbackUrls = Lazy.list({
|
|
180
|
+
produce: () =>
|
|
181
|
+
[
|
|
182
|
+
'http://localhost:4200',
|
|
183
|
+
\`https://\${Stack.of(this).region}.console.aws.amazon.com\`,
|
|
184
|
+
].concat(
|
|
185
|
+
this.findCloudFrontDistributions().map(
|
|
186
|
+
(d) => \`https://\${d.domainName}\`
|
|
187
|
+
)
|
|
188
|
+
),
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return userPool.addClient(WEB_CLIENT_ID, {
|
|
192
|
+
authFlows: {
|
|
193
|
+
userPassword: true,
|
|
194
|
+
userSrp: true,
|
|
195
|
+
user: true,
|
|
196
|
+
},
|
|
197
|
+
oAuth: {
|
|
198
|
+
flows: {
|
|
199
|
+
authorizationCodeGrant: true,
|
|
200
|
+
},
|
|
201
|
+
scopes: [OAuthScope.EMAIL, OAuthScope.OPENID, OAuthScope.PROFILE],
|
|
202
|
+
callbackUrls: lazilyComputedCallbackUrls,
|
|
203
|
+
logoutUrls: lazilyComputedCallbackUrls,
|
|
204
|
+
},
|
|
205
|
+
preventUserExistenceErrors: true,
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
private createIdentityPool = (
|
|
210
|
+
userPool: UserPool,
|
|
211
|
+
userPoolClient: UserPoolClient
|
|
212
|
+
) => {
|
|
213
|
+
const identityPool = new IdentityPool(this, 'IdentityPool');
|
|
214
|
+
|
|
215
|
+
identityPool.addUserPoolAuthentication(
|
|
216
|
+
new UserPoolAuthenticationProvider({
|
|
217
|
+
userPool,
|
|
218
|
+
userPoolClient,
|
|
219
|
+
})
|
|
203
220
|
);
|
|
204
|
-
|
|
221
|
+
|
|
222
|
+
return identityPool;
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
private createManagedLoginBranding = (
|
|
226
|
+
userPool: UserPool,
|
|
227
|
+
userPoolClient: UserPoolClient,
|
|
228
|
+
userPoolDomain: CfnUserPoolDomain
|
|
229
|
+
) => {
|
|
230
|
+
new CfnManagedLoginBranding(this, 'ManagedLoginBranding', {
|
|
231
|
+
userPoolId: userPool.userPoolId,
|
|
232
|
+
clientId: userPoolClient.userPoolClientId,
|
|
233
|
+
useCognitoProvidedValues: true,
|
|
234
|
+
}).node.addDependency(userPoolClient, userPool, userPoolDomain);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
private findCloudFrontDistributions = (): Distribution[] =>
|
|
238
|
+
Stack.of(this)
|
|
239
|
+
.node.findAll()
|
|
240
|
+
.filter((child) => child instanceof Distribution);
|
|
205
241
|
}
|
|
206
242
|
"
|
|
207
243
|
`;
|
|
@@ -228,6 +264,6 @@ export function App() {
|
|
|
228
264
|
`;
|
|
229
265
|
|
|
230
266
|
exports[`cognito-auth generator > should update shared constructs index.ts > common/constructs-index 1`] = `
|
|
231
|
-
"export * from
|
|
232
|
-
export * from './runtime-config
|
|
267
|
+
"export * from "./user-identity.js";
|
|
268
|
+
export * from './runtime-config.js';"
|
|
233
269
|
`;
|
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
|
+
}
|