@liflig/cdk-vy 1.0.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 +373 -0
- package/README.md +52 -0
- package/lib/cognito-app-client/__test__/index.test.d.ts +1 -0
- package/lib/cognito-app-client/__test__/index.test.js +47 -0
- package/lib/cognito-app-client/cognito-app-client.d.ts +165 -0
- package/lib/cognito-app-client/cognito-app-client.js +183 -0
- package/lib/cognito-app-client/handler.d.ts +5 -0
- package/lib/cognito-app-client/handler.js +114 -0
- package/lib/cognito-info.d.ts +49 -0
- package/lib/cognito-info.js +76 -0
- package/lib/cognito-resource-server/__test__/index.test.d.ts +1 -0
- package/lib/cognito-resource-server/__test__/index.test.js +23 -0
- package/lib/cognito-resource-server/cognito-resource-server.d.ts +96 -0
- package/lib/cognito-resource-server/cognito-resource-server.js +120 -0
- package/lib/cognito-resource-server/handler.d.ts +5 -0
- package/lib/cognito-resource-server/handler.js +104 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +12 -0
- package/lib/shared/custom-resource-handler.d.ts +11 -0
- package/lib/shared/custom-resource-handler.js +28 -0
- package/lib/shared/sigv4-client.d.ts +21 -0
- package/lib/shared/sigv4-client.js +53 -0
- package/lib/shared/types.d.ts +93 -0
- package/lib/shared/types.js +22 -0
- package/package.json +71 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDK Construct for Cognito App Client
|
|
3
|
+
*/
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import * as cdk from "aws-cdk-lib";
|
|
8
|
+
import * as iam from "aws-cdk-lib/aws-iam";
|
|
9
|
+
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
10
|
+
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
11
|
+
import * as logs from "aws-cdk-lib/aws-logs";
|
|
12
|
+
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
|
|
13
|
+
import * as cr from "aws-cdk-lib/custom-resources";
|
|
14
|
+
import { Construct } from "constructs";
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = path.dirname(__filename);
|
|
18
|
+
/**
|
|
19
|
+
* Type of app client
|
|
20
|
+
*/
|
|
21
|
+
export var AppClientType;
|
|
22
|
+
(function (AppClientType) {
|
|
23
|
+
/**
|
|
24
|
+
* Backend app client for machine-to-machine (M2M) authentication
|
|
25
|
+
* Uses OAuth 2.0 Client Credentials grant type
|
|
26
|
+
* Generates a client secret for authentication
|
|
27
|
+
*/
|
|
28
|
+
AppClientType["BACKEND"] = "backend";
|
|
29
|
+
/**
|
|
30
|
+
* Frontend app client for user authentication
|
|
31
|
+
* Uses OAuth 2.0 Authorization Code or Implicit grant types
|
|
32
|
+
* Supports callback URLs and logout URLs for browser-based flows
|
|
33
|
+
*/
|
|
34
|
+
AppClientType["FRONTEND"] = "frontend";
|
|
35
|
+
})(AppClientType || (AppClientType = {}));
|
|
36
|
+
/**
|
|
37
|
+
* A Cognito App Client managed through Vy's central Cognito service
|
|
38
|
+
*
|
|
39
|
+
* App clients are the user pool authentication resources attached to your app.
|
|
40
|
+
* Use an app client to configure the permitted authentication actions for an app.
|
|
41
|
+
*
|
|
42
|
+
* There are two types of app clients:
|
|
43
|
+
* - **Backend**: Machine-to-machine authentication using OAuth 2.0 Client Credentials
|
|
44
|
+
* - **Frontend**: User authentication using OAuth 2.0 Authorization Code or Implicit Grant
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* // Backend app client for M2M authentication
|
|
48
|
+
* const backendClient = new CognitoAppClient(this, 'BackendClient', {
|
|
49
|
+
* environment: VyEnvironment.TEST,
|
|
50
|
+
* name: 'my-backend-service',
|
|
51
|
+
* type: AppClientType.BACKEND,
|
|
52
|
+
* scopes: ['https://api.vydev.io/read', 'https://api.vydev.io/write']
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* // Access credentials
|
|
56
|
+
* const clientId = backendClient.clientId;
|
|
57
|
+
* const clientSecret = backendClient.clientSecret; // Stored in Secrets Manager
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Frontend app client for user authentication
|
|
61
|
+
* const frontendClient = new CognitoAppClient(this, 'FrontendClient', {
|
|
62
|
+
* environment: VyEnvironment.PROD,
|
|
63
|
+
* name: 'my-web-app',
|
|
64
|
+
* type: AppClientType.FRONTEND,
|
|
65
|
+
* scopes: ['email', 'openid', 'profile'],
|
|
66
|
+
* callbackUrls: ['https://my-app.vydev.io/auth/callback'],
|
|
67
|
+
* logoutUrls: ['https://my-app.vydev.io/logout']
|
|
68
|
+
* });
|
|
69
|
+
*/
|
|
70
|
+
export class CognitoAppClient extends Construct {
|
|
71
|
+
/**
|
|
72
|
+
* The name of the app client
|
|
73
|
+
*/
|
|
74
|
+
name;
|
|
75
|
+
/**
|
|
76
|
+
* The underlying custom resource
|
|
77
|
+
*/
|
|
78
|
+
resource;
|
|
79
|
+
/**
|
|
80
|
+
* The logGroup for the event handler lambda
|
|
81
|
+
*/
|
|
82
|
+
lambdaLogGroup;
|
|
83
|
+
/**
|
|
84
|
+
* The logGroup for the custom resource provider
|
|
85
|
+
*/
|
|
86
|
+
providerLogGroup;
|
|
87
|
+
/**
|
|
88
|
+
* The client ID for authentication
|
|
89
|
+
*/
|
|
90
|
+
clientId;
|
|
91
|
+
/**
|
|
92
|
+
* The client secret (only for backend clients)
|
|
93
|
+
* If storeSecretInSecretsManager is true, this returns a reference to the secret value
|
|
94
|
+
*/
|
|
95
|
+
clientSecret;
|
|
96
|
+
/**
|
|
97
|
+
* The Secrets Manager secret containing the client secret
|
|
98
|
+
* Only available if storeSecretInSecretsManager is true and type is backend
|
|
99
|
+
*/
|
|
100
|
+
clientSecretSecret;
|
|
101
|
+
constructor(scope, id, props) {
|
|
102
|
+
super(scope, id);
|
|
103
|
+
this.name = props.name;
|
|
104
|
+
if (props.type === AppClientType.FRONTEND &&
|
|
105
|
+
props.callbackUrls &&
|
|
106
|
+
props.callbackUrls.length === 0) {
|
|
107
|
+
cdk.Annotations.of(this).addWarning("Frontend app clients typically require callbackUrls for OAuth flows");
|
|
108
|
+
}
|
|
109
|
+
this.lambdaLogGroup = new logs.LogGroup(this, "LambdaLogGroup", {
|
|
110
|
+
retention: props.logsRetention ?? logs.RetentionDays.ONE_WEEK,
|
|
111
|
+
});
|
|
112
|
+
const onEventHandler = new NodejsFunction(this, "OnEventHandler", {
|
|
113
|
+
runtime: lambda.Runtime.NODEJS_22_X,
|
|
114
|
+
handler: "handler",
|
|
115
|
+
entry: require.resolve(`${__dirname}/handler`),
|
|
116
|
+
timeout: cdk.Duration.minutes(2),
|
|
117
|
+
memorySize: 256,
|
|
118
|
+
logGroup: this.lambdaLogGroup,
|
|
119
|
+
environment: props.cognitoBaseDomain
|
|
120
|
+
? {
|
|
121
|
+
COGNITO_BASE_DOMAIN: props.cognitoBaseDomain,
|
|
122
|
+
}
|
|
123
|
+
: undefined,
|
|
124
|
+
bundling: {
|
|
125
|
+
minify: true,
|
|
126
|
+
sourceMap: true,
|
|
127
|
+
target: "es2020",
|
|
128
|
+
externalModules: ["aws-sdk"],
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
onEventHandler.addToRolePolicy(new iam.PolicyStatement({
|
|
132
|
+
effect: iam.Effect.ALLOW,
|
|
133
|
+
actions: ["execute-api:Invoke"],
|
|
134
|
+
resources: ["*"], // Can be scoped down if API Gateway ARN is known
|
|
135
|
+
}));
|
|
136
|
+
this.providerLogGroup = new logs.LogGroup(this, "ProviderLogGroup", {
|
|
137
|
+
retention: props.logsRetention ?? logs.RetentionDays.ONE_WEEK,
|
|
138
|
+
});
|
|
139
|
+
const provider = new cr.Provider(this, "Provider", {
|
|
140
|
+
onEventHandler,
|
|
141
|
+
logGroup: this.providerLogGroup,
|
|
142
|
+
});
|
|
143
|
+
this.resource = new cdk.CustomResource(this, "Resource", {
|
|
144
|
+
serviceToken: provider.serviceToken,
|
|
145
|
+
properties: {
|
|
146
|
+
Environment: props.environment,
|
|
147
|
+
Name: props.name,
|
|
148
|
+
Type: props.type,
|
|
149
|
+
Scopes: props.scopes || [],
|
|
150
|
+
CallbackUrls: props.callbackUrls || [],
|
|
151
|
+
LogoutUrls: props.logoutUrls || [],
|
|
152
|
+
GenerateSecret: props.generateSecret,
|
|
153
|
+
},
|
|
154
|
+
// Force replacement if type changes
|
|
155
|
+
resourceType: "Custom::VyCognitoAppClient",
|
|
156
|
+
});
|
|
157
|
+
this.clientId = this.resource.getAttString("ClientId");
|
|
158
|
+
const shouldStoreSecret = props.storeSecretInSecretsManager !== false;
|
|
159
|
+
if (props.type === AppClientType.BACKEND && shouldStoreSecret) {
|
|
160
|
+
const secretValue = this.resource.getAttString("ClientSecret");
|
|
161
|
+
this.clientSecretSecret = new secretsmanager.Secret(this, "ClientSecret", {
|
|
162
|
+
secretName: props.secretName ??
|
|
163
|
+
`vy/${props.environment}/cognito/app-client/${props.name}`,
|
|
164
|
+
description: `Client secret for Vy Cognito app client ${props.name}`,
|
|
165
|
+
secretStringValue: cdk.SecretValue.unsafePlainText(secretValue),
|
|
166
|
+
});
|
|
167
|
+
this.clientSecret = this.clientSecretSecret.secretValue.unsafeUnwrap();
|
|
168
|
+
}
|
|
169
|
+
else if (props.type === AppClientType.BACKEND) {
|
|
170
|
+
this.clientSecret = this.resource.getAttString("ClientSecret");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Grant read access to the client secret (if it exists in Secrets Manager)
|
|
175
|
+
*/
|
|
176
|
+
grantReadSecret(grantee) {
|
|
177
|
+
if (!this.clientSecretSecret) {
|
|
178
|
+
throw new Error("Client secret is not stored in Secrets Manager");
|
|
179
|
+
}
|
|
180
|
+
return this.clientSecretSecret.grantRead(grantee);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29nbml0by1hcHAtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvZ25pdG8tYXBwLWNsaWVudC9jb2duaXRvLWFwcC1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQzNDLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFBO0FBQ2pDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFDeEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxhQUFhLENBQUE7QUFDbEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxxQkFBcUIsQ0FBQTtBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLHdCQUF3QixDQUFBO0FBQ2hELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQTtBQUM5RCxPQUFPLEtBQUssSUFBSSxNQUFNLHNCQUFzQixDQUFBO0FBQzVDLE9BQU8sS0FBSyxjQUFjLE1BQU0sZ0NBQWdDLENBQUE7QUFDaEUsT0FBTyxLQUFLLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBR3RDLE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQzlDLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ2pELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7QUFFMUM7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxhQWNYO0FBZEQsV0FBWSxhQUFhO0lBQ3ZCOzs7O09BSUc7SUFDSCxvQ0FBbUIsQ0FBQTtJQUVuQjs7OztPQUlHO0lBQ0gsc0NBQXFCLENBQUE7QUFDdkIsQ0FBQyxF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QWUsQ0FBQyxXQUFXLENBQUM7YUFDaEUsQ0FDRixDQUFBO1lBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQ3hFLENBQUM7YUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2hELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDaEUsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLGVBQWUsQ0FBQyxPQUF1QjtRQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQyxDQUFBO1FBQ25FLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDbkQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDREsgQ29uc3RydWN0IGZvciBDb2duaXRvIEFwcCBDbGllbnRcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVSZXF1aXJlIH0gZnJvbSBcIm5vZGU6bW9kdWxlXCJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcIm5vZGU6dXJsXCJcbmltcG9ydCAqIGFzIGNkayBmcm9tIFwiYXdzLWNkay1saWJcIlxuaW1wb3J0ICogYXMgaWFtIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCJcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiXG5pbXBvcnQgeyBOb2RlanNGdW5jdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqc1wiXG5pbXBvcnQgKiBhcyBsb2dzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiXG5pbXBvcnQgKiBhcyBzZWNyZXRzbWFuYWdlciBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNlY3JldHNtYW5hZ2VyXCJcbmltcG9ydCAqIGFzIGNyIGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCJcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCB0eXBlIHsgVnlFbnZpcm9ubWVudCB9IGZyb20gXCIuLi9zaGFyZWQvdHlwZXNcIlxuXG5jb25zdCByZXF1aXJlID0gY3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpXG5jb25zdCBfX2ZpbGVuYW1lID0gZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpXG5jb25zdCBfX2Rpcm5hbWUgPSBwYXRoLmRpcm5hbWUoX19maWxlbmFtZSlcblxuLyoqXG4gKiBUeXBlIG9mIGFwcCBjbGllbnRcbiAqL1xuZXhwb3J0IGVudW0gQXBwQ2xpZW50VHlwZSB7XG4gIC8qKlxuICAgKiBCYWNrZW5kIGFwcCBjbGllbnQgZm9yIG1hY2hpbmUtdG8tbWFjaGluZSAoTTJNKSBhdXRoZW50aWNhdGlvblxuICAgKiBVc2VzIE9BdXRoIDIuMCBDbGllbnQgQ3JlZGVudGlhbHMgZ3JhbnQgdHlwZVxuICAgKiBHZW5lcmF0ZXMgYSBjbGllbnQgc2VjcmV0IGZvciBhdXRoZW50aWNhdGlvblxuICAgKi9cbiAgQkFDS0VORCA9IFwiYmFja2VuZFwiLFxuXG4gIC8qKlxuICAgKiBGcm9udGVuZCBhcHAgY2xpZW50IGZvciB1c2VyIGF1dGhlbnRpY2F0aW9uXG4gICAqIFVzZXMgT0F1dGggMi4wIEF1dGhvcml6YXRpb24gQ29kZSBvciBJbXBsaWNpdCBncmFudCB0eXBlc1xuICAgKiBTdXBwb3J0cyBjYWxsYmFjayBVUkxzIGFuZCBsb2dvdXQgVVJMcyBmb3IgYnJvd3Nlci1iYXNlZCBmbG93c1xuICAgKi9cbiAgRlJPTlRFTkQgPSBcImZyb250ZW5kXCIsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29nbml0b0FwcENsaWVudFByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBWeSBlbnZpcm9ubWVudCB0byBwcm92aXNpb24gaW4gKGUuZy4sIFZ5RW52aXJvbm1lbnQuUFJPRCwgVnlFbnZpcm9ubWVudC5TVEFHRSwgVnlFbnZpcm9ubWVudC5URVNUKVxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ6IFZ5RW52aXJvbm1lbnRcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGFwcCBjbGllbnRcbiAgICogTXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBlbnZpcm9ubWVudFxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIGFwcCBjbGllbnRcbiAgICogLSBiYWNrZW5kOiBNYWNoaW5lLXRvLW1hY2hpbmUgYXV0aGVudGljYXRpb24gd2l0aCBjbGllbnQgY3JlZGVudGlhbHNcbiAgICogLSBmcm9udGVuZDogVXNlciBhdXRoZW50aWNhdGlvbiB3aXRoIGF1dGhvcml6YXRpb24gY29kZSBvciBpbXBsaWNpdCBncmFudFxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogQXBwQ2xpZW50VHlwZVxuXG4gIC8qKlxuICAgKiBPQXV0aCBzY29wZXMgZm9yIHRoaXMgY2xpZW50XG4gICAqXG4gICAqIEZvciBiYWNrZW5kIGNsaWVudHM6IFVzZSByZXNvdXJjZSBzZXJ2ZXIgc2NvcGVzIChlLmcuLCAnaHR0cHM6Ly9hcGkudnlkZXYuaW8vcmVhZCcpXG4gICAqIEZvciBmcm9udGVuZCBjbGllbnRzOiBVc2UgT0lEQyBzY29wZXMgKGUuZy4sICdlbWFpbCcsICdvcGVuaWQnLCAncHJvZmlsZScpXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gRW1wdHkgYXJyYXlcbiAgICovXG4gIHJlYWRvbmx5IHNjb3Blcz86IHN0cmluZ1tdXG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIFVSTHMgZm9yIE9BdXRoIGZsb3dzXG4gICAqIE9ubHkgdXNlZCB3aXRoIGZyb250ZW5kIGNsaWVudHNcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBjYWxsYmFjayBVUkxzXG4gICAqL1xuICByZWFkb25seSBjYWxsYmFja1VybHM/OiBzdHJpbmdbXVxuXG4gIC8qKlxuICAgKiBMb2dvdXQgVVJMcyBmb3IgT0F1dGggZmxvd3NcbiAgICogT25seSB1c2VkIHdpdGggZnJvbnRlbmQgY2xpZW50c1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGxvZ291dCBVUkxzXG4gICAqL1xuICByZWFkb25seSBsb2dvdXRVcmxzPzogc3RyaW5nW11cblxuICAvKipcbiAgICogV2hldGhlciB0byBnZW5lcmF0ZSBhIGNsaWVudCBzZWNyZXRcbiAgICogQXV0b21hdGljYWxseSBzZXQgYmFzZWQgb24gdHlwZSwgYnV0IGNhbiBiZSBvdmVycmlkZGVuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdHJ1ZSBmb3IgYmFja2VuZCwgZmFsc2UgZm9yIGZyb250ZW5kXG4gICAqL1xuICByZWFkb25seSBnZW5lcmF0ZVNlY3JldD86IGJvb2xlYW5cblxuICAvKipcbiAgICogV2hldGhlciB0byBzdG9yZSB0aGUgY2xpZW50IHNlY3JldCBpbiBBV1MgU2VjcmV0cyBNYW5hZ2VyXG4gICAqIE9ubHkgYXBwbGljYWJsZSBpZiBnZW5lcmF0ZVNlY3JldCBpcyB0cnVlXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHN0b3JlU2VjcmV0SW5TZWNyZXRzTWFuYWdlcj86IGJvb2xlYW5cblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgc2VjcmV0IGluIEFXUyBTZWNyZXRzIE1hbmFnZXJcbiAgICogT25seSBhcHBsaWNhYmxlIGlmIGdlbmVyYXRlU2VjcmV0IGlzIHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHNlY3JldE5hbWU/OiBzdHJpbmdcblxuICAvKipcbiAgICogQmFzZSBkb21haW4gZm9yIENvZ25pdG8gc2VydmljZVxuICAgKiBAZGVmYXVsdCAnY29nbml0by52eWRldi5pbydcbiAgICovXG4gIHJlYWRvbmx5IGNvZ25pdG9CYXNlRG9tYWluPzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIEBkZWZhdWx0IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfV0VFS1xuICAgKi9cbiAgcmVhZG9ubHkgbG9nc1JldGVudGlvbj86IGxvZ3MuUmV0ZW50aW9uRGF5c1xufVxuXG4vKipcbiAqIEEgQ29nbml0byBBcHAgQ2xpZW50IG1hbmFnZWQgdGhyb3VnaCBWeSdzIGNlbnRyYWwgQ29nbml0byBzZXJ2aWNlXG4gKlxuICogQXBwIGNsaWVudHMgYXJlIHRoZSB1c2VyIHBvb2wgYXV0aGVudGljYXRpb24gcmVzb3VyY2VzIGF0dGFjaGVkIHRvIHlvdXIgYXBwLlxuICogVXNlIGFuIGFwcCBjbGllbnQgdG8gY29uZmlndXJlIHRoZSBwZXJtaXR0ZWQgYXV0aGVudGljYXRpb24gYWN0aW9ucyBmb3IgYW4gYXBwLlxuICpcbiAqIFRoZXJlIGFyZSB0d28gdHlwZXMgb2YgYXBwIGNsaWVudHM6XG4gKiAtICoqQmFja2VuZCoqOiBNYWNoaW5lLXRvLW1hY2hpbmUgYXV0aGVudGljYXRpb24gdXNpbmcgT0F1dGggMi4wIENsaWVudCBDcmVkZW50aWFsc1xuICogLSAqKkZyb250ZW5kKio6IFVzZXIgYXV0aGVudGljYXRpb24gdXNpbmcgT0F1dGggMi4wIEF1dGhvcml6YXRpb24gQ29kZSBvciBJbXBsaWNpdCBHcmFudFxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBCYWNrZW5kIGFwcCBjbGllbnQgZm9yIE0yTSBhdXRoZW50aWNhdGlvblxuICogY29uc3QgYmFja2VuZENsaWVudCA9IG5ldyBDb2duaXRvQXBwQ2xpZW50KHRoaXMsICdCYWNrZW5kQ2xpZW50Jywge1xuICogICBlbnZpcm9ubWVudDogVnlFbnZpcm9ubWVudC5URVNULFxuICogICBuYW1lOiAnbXktYmFja2VuZC1zZXJ2aWNlJyxcbiAqICAgdHlwZTogQXBwQ2xpZW50VHlwZS5CQUNLRU5ELFxuICogICBzY29wZXM6IFsnaHR0cHM6Ly9hcGkudnlkZXYuaW8vcmVhZCcsICdodHRwczovL2FwaS52eWRldi5pby93cml0ZSddXG4gKiB9KTtcbiAqXG4gKiAvLyBBY2Nlc3MgY3JlZGVudGlhbHNcbiAqIGNvbnN0IGNsaWVudElkID0gYmFja2VuZENsaWVudC5jbGllbnRJZDtcbiAqIGNvbnN0IGNsaWVudFNlY3JldCA9IGJhY2tlbmRDbGllbnQuY2xpZW50U2VjcmV0OyAvLyBTdG9yZWQgaW4gU2VjcmV0cyBNYW5hZ2VyXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEZyb250ZW5kIGFwcCBjbGllbnQgZm9yIHVzZXIgYXV0aGVudGljYXRpb25cbiAqIGNvbnN0IGZyb250ZW5kQ2xpZW50ID0gbmV3IENvZ25pdG9BcHBDbGllbnQodGhpcywgJ0Zyb250ZW5kQ2xpZW50Jywge1xuICogICBlbnZpcm9ubWVudDogVnlFbnZpcm9ubWVudC5QUk9ELFxuICogICBuYW1lOiAnbXktd2ViLWFwcCcsXG4gKiAgIHR5cGU6IEFwcENsaWVudFR5cGUuRlJPTlRFTkQsXG4gKiAgIHNjb3BlczogWydlbWFpbCcsICdvcGVuaWQnLCAncHJvZmlsZSddLFxuICogICBjYWxsYmFja1VybHM6IFsnaHR0cHM6Ly9teS1hcHAudnlkZXYuaW8vYXV0aC9jYWxsYmFjayddLFxuICogICBsb2dvdXRVcmxzOiBbJ2h0dHBzOi8vbXktYXBwLnZ5ZGV2LmlvL2xvZ291dCddXG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNsYXNzIENvZ25pdG9BcHBDbGllbnQgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGFwcCBjbGllbnRcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmdcblxuICAvKipcbiAgICogVGhlIHVuZGVybHlpbmcgY3VzdG9tIHJlc291cmNlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcmVzb3VyY2U6IGNkay5DdXN0b21SZXNvdXJjZVxuXG4gIC8qKlxuICAgKiBUaGUgbG9nR3JvdXAgZm9yIHRoZSBldmVudCBoYW5kbGVyIGxhbWJkYVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGxhbWJkYUxvZ0dyb3VwOiBsb2dzLkxvZ0dyb3VwXG5cbiAgLyoqXG4gICAqIFRoZSBsb2dHcm91cCBmb3IgdGhlIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlclxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHByb3ZpZGVyTG9nR3JvdXA6IGxvZ3MuTG9nR3JvdXBcblxuICAvKipcbiAgICogVGhlIGNsaWVudCBJRCBmb3IgYXV0aGVudGljYXRpb25cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjbGllbnRJZDogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBjbGllbnQgc2VjcmV0IChvbmx5IGZvciBiYWNrZW5kIGNsaWVudHMpXG4gICAqIElmIHN0b3JlU2VjcmV0SW5TZWNyZXRzTWFuYWdlciBpcyB0cnVlLCB0aGlzIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHNlY3JldCB2YWx1ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNsaWVudFNlY3JldD86IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBUaGUgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIHRoZSBjbGllbnQgc2VjcmV0XG4gICAqIE9ubHkgYXZhaWxhYmxlIGlmIHN0b3JlU2VjcmV0SW5TZWNyZXRzTWFuYWdlciBpcyB0cnVlIGFuZCB0eXBlIGlzIGJhY2tlbmRcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjbGllbnRTZWNyZXRTZWNyZXQ/OiBzZWNyZXRzbWFuYWdlci5JU2VjcmV0XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENvZ25pdG9BcHBDbGllbnRQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIHRoaXMubmFtZSA9IHByb3BzLm5hbWVcblxuICAgIGlmIChcbiAgICAgIHByb3BzLnR5cGUgPT09IEFwcENsaWVudFR5cGUuRlJPTlRFTkQgJiZcbiAgICAgIHByb3BzLmNhbGxiYWNrVXJscyAmJlxuICAgICAgcHJvcHMuY2FsbGJhY2tVcmxzLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgY2RrLkFubm90YXRpb25zLm9mKHRoaXMpLmFkZFdhcm5pbmcoXG4gICAgICAgIFwiRnJvbnRlbmQgYXBwIGNsaWVudHMgdHlwaWNhbGx5IHJlcXVpcmUgY2FsbGJhY2tVcmxzIGZvciBPQXV0aCBmbG93c1wiLFxuICAgICAgKVxuICAgIH1cblxuICAgIHRoaXMubGFtYmRhTG9nR3JvdXAgPSBuZXcgbG9ncy5Mb2dHcm91cCh0aGlzLCBcIkxhbWJkYUxvZ0dyb3VwXCIsIHtcbiAgICAgIHJldGVudGlvbjogcHJvcHMubG9nc1JldGVudGlvbiA/PyBsb2dzLlJldGVudGlvbkRheXMuT05FX1dFRUssXG4gICAgfSlcblxuICAgIGNvbnN0IG9uRXZlbnRIYW5kbGVyID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsIFwiT25FdmVudEhhbmRsZXJcIiwge1xuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICBoYW5kbGVyOiBcImhhbmRsZXJcIixcbiAgICAgIGVudHJ5OiByZXF1aXJlLnJlc29sdmUoYCR7X19kaXJuYW1lfS9oYW5kbGVyYCksXG4gICAgICB0aW1lb3V0OiBjZGsuRHVyYXRpb24ubWludXRlcygyKSxcbiAgICAgIG1lbW9yeVNpemU6IDI1NixcbiAgICAgIGxvZ0dyb3VwOiB0aGlzLmxhbWJkYUxvZ0dyb3VwLFxuICAgICAgZW52aXJvbm1lbnQ6IHByb3BzLmNvZ25pdG9CYXNlRG9tYWluXG4gICAgICAgID8ge1xuICAgICAgICAgICAgQ09HTklUT19CQVNFX0RPTUFJTjogcHJvcHMuY29nbml0b0Jhc2VEb21haW4sXG4gICAgICAgICAgfVxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIGJ1bmRsaW5nOiB7XG4gICAgICAgIG1pbmlmeTogdHJ1ZSxcbiAgICAgICAgc291cmNlTWFwOiB0cnVlLFxuICAgICAgICB0YXJnZXQ6IFwiZXMyMDIwXCIsXG4gICAgICAgIGV4dGVybmFsTW9kdWxlczogW1wiYXdzLXNka1wiXSxcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIG9uRXZlbnRIYW5kbGVyLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgICBhY3Rpb25zOiBbXCJleGVjdXRlLWFwaTpJbnZva2VcIl0sXG4gICAgICAgIHJlc291cmNlczogW1wiKlwiXSwgLy8gQ2FuIGJlIHNjb3BlZCBkb3duIGlmIEFQSSBHYXRld2F5IEFSTiBpcyBrbm93blxuICAgICAgfSksXG4gICAgKVxuXG4gICAgdGhpcy5wcm92aWRlckxvZ0dyb3VwID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcywgXCJQcm92aWRlckxvZ0dyb3VwXCIsIHtcbiAgICAgIHJldGVudGlvbjogcHJvcHMubG9nc1JldGVudGlvbiA/PyBsb2dzLlJldGVudGlvbkRheXMuT05FX1dFRUssXG4gICAgfSlcblxuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IGNyLlByb3ZpZGVyKHRoaXMsIFwiUHJvdmlkZXJcIiwge1xuICAgICAgb25FdmVudEhhbmRsZXIsXG4gICAgICBsb2dHcm91cDogdGhpcy5wcm92aWRlckxvZ0dyb3VwLFxuICAgIH0pXG5cbiAgICB0aGlzLnJlc291cmNlID0gbmV3IGNkay5DdXN0b21SZXNvdXJjZSh0aGlzLCBcIlJlc291cmNlXCIsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBFbnZpcm9ubWVudDogcHJvcHMuZW52aXJvbm1lbnQsXG4gICAgICAgIE5hbWU6IHByb3BzLm5hbWUsXG4gICAgICAgIFR5cGU6IHByb3BzLnR5cGUsXG4gICAgICAgIFNjb3BlczogcHJvcHMuc2NvcGVzIHx8IFtdLFxuICAgICAgICBDYWxsYmFja1VybHM6IHByb3BzLmNhbGxiYWNrVXJscyB8fCBbXSxcbiAgICAgICAgTG9nb3V0VXJsczogcHJvcHMubG9nb3V0VXJscyB8fCBbXSxcbiAgICAgICAgR2VuZXJhdGVTZWNyZXQ6IHByb3BzLmdlbmVyYXRlU2VjcmV0LFxuICAgICAgfSxcbiAgICAgIC8vIEZvcmNlIHJlcGxhY2VtZW50IGlmIHR5cGUgY2hhbmdlc1xuICAgICAgcmVzb3VyY2VUeXBlOiBcIkN1c3RvbTo6VnlDb2duaXRvQXBwQ2xpZW50XCIsXG4gICAgfSlcblxuICAgIHRoaXMuY2xpZW50SWQgPSB0aGlzLnJlc291cmNlLmdldEF0dFN0cmluZyhcIkNsaWVudElkXCIpXG5cbiAgICBjb25zdCBzaG91bGRTdG9yZVNlY3JldCA9IHByb3BzLnN0b3JlU2VjcmV0SW5TZWNyZXRzTWFuYWdlciAhPT0gZmFsc2VcbiAgICBpZiAocHJvcHMudHlwZSA9PT0gQXBwQ2xpZW50VHlwZS5CQUNLRU5EICYmIHNob3VsZFN0b3JlU2VjcmV0KSB7XG4gICAgICBjb25zdCBzZWNyZXRWYWx1ZSA9IHRoaXMucmVzb3VyY2UuZ2V0QXR0U3RyaW5nKFwiQ2xpZW50U2VjcmV0XCIpXG5cbiAgICAgIHRoaXMuY2xpZW50U2VjcmV0U2VjcmV0ID0gbmV3IHNlY3JldHNtYW5hZ2VyLlNlY3JldChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgXCJDbGllbnRTZWNyZXRcIixcbiAgICAgICAge1xuICAgICAgICAgIHNlY3JldE5hbWU6XG4gICAgICAgICAgICBwcm9wcy5zZWNyZXROYW1lID8/XG4gICAgICAgICAgICBgdnkvJHtwcm9wcy5lbnZpcm9ubWVudH0vY29nbml0by9hcHAtY2xpZW50LyR7cHJvcHMubmFtZX1gLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgQ2xpZW50IHNlY3JldCBmb3IgVnkgQ29nbml0byBhcHAgY2xpZW50ICR7cHJvcHMubmFtZX1gLFxuICAgICAgICAgIHNlY3JldFN0cmluZ1ZhbHVlOiBjZGsuU2VjcmV0VmFsdWUudW5zYWZlUGxhaW5UZXh0KHNlY3JldFZhbHVlKSxcbiAgICAgICAgfSxcbiAgICAgIClcblxuICAgICAgdGhpcy5jbGllbnRTZWNyZXQgPSB0aGlzLmNsaWVudFNlY3JldFNlY3JldC5zZWNyZXRWYWx1ZS51bnNhZmVVbndyYXAoKVxuICAgIH0gZWxzZSBpZiAocHJvcHMudHlwZSA9PT0gQXBwQ2xpZW50VHlwZS5CQUNLRU5EKSB7XG4gICAgICB0aGlzLmNsaWVudFNlY3JldCA9IHRoaXMucmVzb3VyY2UuZ2V0QXR0U3RyaW5nKFwiQ2xpZW50U2VjcmV0XCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50IHJlYWQgYWNjZXNzIHRvIHRoZSBjbGllbnQgc2VjcmV0IChpZiBpdCBleGlzdHMgaW4gU2VjcmV0cyBNYW5hZ2VyKVxuICAgKi9cbiAgcHVibGljIGdyYW50UmVhZFNlY3JldChncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudCB7XG4gICAgaWYgKCF0aGlzLmNsaWVudFNlY3JldFNlY3JldCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2xpZW50IHNlY3JldCBpcyBub3Qgc3RvcmVkIGluIFNlY3JldHMgTWFuYWdlclwiKVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jbGllbnRTZWNyZXRTZWNyZXQuZ3JhbnRSZWFkKGdyYW50ZWUpXG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lambda handler for CognitoAppClient custom resource
|
|
3
|
+
*/
|
|
4
|
+
import { createFailureResponse, createSuccessResponse, handleError, } from "../shared/custom-resource-handler";
|
|
5
|
+
import { createUrlFromEnvironment, signedRequest } from "../shared/sigv4-client";
|
|
6
|
+
const COGNITO_BASE_DOMAIN = process.env.COGNITO_BASE_DOMAIN || "cognito.vydev.io";
|
|
7
|
+
async function createAppClient(baseUrl, client) {
|
|
8
|
+
const response = await signedRequest({
|
|
9
|
+
method: "POST",
|
|
10
|
+
hostname: baseUrl,
|
|
11
|
+
path: "/app-clients",
|
|
12
|
+
body: JSON.stringify(client),
|
|
13
|
+
});
|
|
14
|
+
if (response.statusCode !== 201) {
|
|
15
|
+
throw new Error(`Could not create resource: ${response.statusCode} - ${response.body}`);
|
|
16
|
+
}
|
|
17
|
+
return JSON.parse(response.body);
|
|
18
|
+
}
|
|
19
|
+
async function readAppClient(baseUrl, name) {
|
|
20
|
+
const encodedName = encodeURIComponent(name);
|
|
21
|
+
const response = await signedRequest({
|
|
22
|
+
method: "GET",
|
|
23
|
+
hostname: baseUrl,
|
|
24
|
+
path: `/app-clients/${encodedName}`,
|
|
25
|
+
});
|
|
26
|
+
if (response.statusCode !== 200) {
|
|
27
|
+
throw new Error(`Could not read resource: ${response.statusCode} - ${response.body}`);
|
|
28
|
+
}
|
|
29
|
+
return JSON.parse(response.body);
|
|
30
|
+
}
|
|
31
|
+
async function updateAppClient(baseUrl, update) {
|
|
32
|
+
const encodedName = encodeURIComponent(update.name);
|
|
33
|
+
const response = await signedRequest({
|
|
34
|
+
method: "PUT",
|
|
35
|
+
hostname: baseUrl,
|
|
36
|
+
path: `/app-clients/${encodedName}`,
|
|
37
|
+
body: JSON.stringify(update),
|
|
38
|
+
});
|
|
39
|
+
if (response.statusCode !== 200) {
|
|
40
|
+
throw new Error(`Could not update resource: ${response.statusCode} - ${response.body}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function deleteAppClient(baseUrl, name) {
|
|
44
|
+
const encodedName = encodeURIComponent(name);
|
|
45
|
+
const response = await signedRequest({
|
|
46
|
+
method: "DELETE",
|
|
47
|
+
hostname: baseUrl,
|
|
48
|
+
path: `/app-clients/${encodedName}`,
|
|
49
|
+
});
|
|
50
|
+
if (response.statusCode !== 200) {
|
|
51
|
+
throw new Error(`Could not delete resource: ${response.statusCode} - ${response.body}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function handler(event) {
|
|
55
|
+
const props = event.ResourceProperties;
|
|
56
|
+
const baseUrl = createUrlFromEnvironment(COGNITO_BASE_DOMAIN, "delegated", props.Environment);
|
|
57
|
+
try {
|
|
58
|
+
switch (event.RequestType) {
|
|
59
|
+
case "Create": {
|
|
60
|
+
// We receive a string value for GenerateSecret, but we need a boolean
|
|
61
|
+
// See https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/1037
|
|
62
|
+
const generate_secret = typeof props.GenerateSecret === "boolean"
|
|
63
|
+
? props.GenerateSecret
|
|
64
|
+
: props.GenerateSecret === "true";
|
|
65
|
+
const client = {
|
|
66
|
+
name: props.Name,
|
|
67
|
+
type: props.Type,
|
|
68
|
+
scopes: props.Scopes || [],
|
|
69
|
+
callback_urls: props.CallbackUrls || [],
|
|
70
|
+
logout_urls: props.LogoutUrls || [],
|
|
71
|
+
generate_secret,
|
|
72
|
+
};
|
|
73
|
+
const created = await createAppClient(baseUrl, client);
|
|
74
|
+
return createSuccessResponse(event.PhysicalResourceId ?? created.name, {
|
|
75
|
+
Name: created.name,
|
|
76
|
+
ClientId: created.client_id || "",
|
|
77
|
+
ClientSecret: created.client_secret || "",
|
|
78
|
+
Type: created.type,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
case "Update": {
|
|
82
|
+
// Check if Type changed (requires replacement)
|
|
83
|
+
const oldProps = event.OldResourceProperties;
|
|
84
|
+
if (oldProps && oldProps.Type !== props.Type) {
|
|
85
|
+
throw new Error("Cannot change app client type. This requires resource replacement.");
|
|
86
|
+
}
|
|
87
|
+
const update = {
|
|
88
|
+
name: props.Name,
|
|
89
|
+
scopes: props.Scopes || [],
|
|
90
|
+
callback_urls: props.CallbackUrls || [],
|
|
91
|
+
logout_urls: props.LogoutUrls || [],
|
|
92
|
+
};
|
|
93
|
+
await updateAppClient(baseUrl, update);
|
|
94
|
+
const updated = await readAppClient(baseUrl, props.Name);
|
|
95
|
+
return createSuccessResponse(event.PhysicalResourceId ?? updated.name, {
|
|
96
|
+
Name: updated.name,
|
|
97
|
+
ClientId: updated.client_id || "",
|
|
98
|
+
ClientSecret: updated.client_secret || "",
|
|
99
|
+
Type: updated.type,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
case "Delete": {
|
|
103
|
+
const name = event.PhysicalResourceId || props.Name;
|
|
104
|
+
await deleteAppClient(baseUrl, name);
|
|
105
|
+
return createSuccessResponse(name, {});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error("Error:", error);
|
|
111
|
+
return createFailureResponse(event.PhysicalResourceId || props.Name || "unknown", handleError(error));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb2duaXRvLWFwcC1jbGllbnQvaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sRUFDTCxxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLFdBQVcsR0FDWixNQUFNLG1DQUFtQyxDQUFBO0FBQzFDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQVFoRixNQUFNLG1CQUFtQixHQUN2QixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLGtCQUFrQixDQUFBO0FBWXZELEtBQUssVUFBVSxlQUFlLENBQzVCLE9BQWUsRUFDZixNQUFpQjtJQUVqQixNQUFNLFFBQVEsR0FBRyxNQUFNLGFBQWEsQ0FBQztRQUNuQyxNQUFNLEVBQUUsTUFBTTtRQUNkLFFBQVEsRUFBRSxPQUFPO1FBQ2pCLElBQUksRUFBRSxjQUFjO1FBQ3BCLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztLQUM3QixDQUFDLENBQUE7SUFFRixJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FDYiw4QkFBOEIsUUFBUSxDQUFDLFVBQVUsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQ3ZFLENBQUE7SUFDSCxDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtBQUNsQyxDQUFDO0FBRUQsS0FBSyxVQUFVLGFBQWEsQ0FDMUIsT0FBZSxFQUNmLElBQVk7SUFFWixNQUFNLFdBQVcsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM1QyxNQUFNLFFBQVEsR0FBRyxNQUFNLGFBQWEsQ0FBQztRQUNuQyxNQUFNLEVBQUUsS0FBSztRQUNiLFFBQVEsRUFBRSxPQUFP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SSxFQUFFLE9BQU8sQ0FBQyxJQUFJO2lCQUNuQixDQUEyQixDQUFBO1lBQzlCLENBQUM7WUFFRCxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ2QsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUE7Z0JBQ25ELE1BQU0sZUFBZSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQTtnQkFFcEMsT0FBTyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUEyQixDQUFBO1lBQ2xFLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUM5QixPQUFPLHFCQUFxQixDQUMxQixLQUFLLENBQUMsa0JBQWtCLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxTQUFTLEVBQ25ELFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FDTyxDQUFBO0lBQzdCLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMYW1iZGEgaGFuZGxlciBmb3IgQ29nbml0b0FwcENsaWVudCBjdXN0b20gcmVzb3VyY2VcbiAqL1xuXG5pbXBvcnQge1xuICBjcmVhdGVGYWlsdXJlUmVzcG9uc2UsXG4gIGNyZWF0ZVN1Y2Nlc3NSZXNwb25zZSxcbiAgaGFuZGxlRXJyb3IsXG59IGZyb20gXCIuLi9zaGFyZWQvY3VzdG9tLXJlc291cmNlLWhhbmRsZXJcIlxuaW1wb3J0IHsgY3JlYXRlVXJsRnJvbUVudmlyb25tZW50LCBzaWduZWRSZXF1ZXN0IH0gZnJvbSBcIi4uL3NoYXJlZC9zaWd2NC1jbGllbnRcIlxuaW1wb3J0IHR5cGUge1xuICBBcHBDbGllbnQsXG4gIEFwcENsaWVudFVwZGF0ZVJlcXVlc3QsXG4gIEN1c3RvbVJlc291cmNlUmVxdWVzdCxcbiAgQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSxcbn0gZnJvbSBcIi4uL3NoYXJlZC90eXBlc1wiXG5cbmNvbnN0IENPR05JVE9fQkFTRV9ET01BSU4gPVxuICBwcm9jZXNzLmVudi5DT0dOSVRPX0JBU0VfRE9NQUlOIHx8IFwiY29nbml0by52eWRldi5pb1wiXG5cbmludGVyZmFjZSBBcHBDbGllbnRQcm9wZXJ0aWVzIHtcbiAgRW52aXJvbm1lbnQ6IHN0cmluZ1xuICBOYW1lOiBzdHJpbmdcbiAgVHlwZTogXCJmcm9udGVuZFwiIHwgXCJiYWNrZW5kXCJcbiAgU2NvcGVzPzogc3RyaW5nW11cbiAgQ2FsbGJhY2tVcmxzPzogc3RyaW5nW11cbiAgTG9nb3V0VXJscz86IHN0cmluZ1tdXG4gIEdlbmVyYXRlU2VjcmV0PzogYm9vbGVhblxufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVBcHBDbGllbnQoXG4gIGJhc2VVcmw6IHN0cmluZyxcbiAgY2xpZW50OiBBcHBDbGllbnQsXG4pOiBQcm9taXNlPEFwcENsaWVudD4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNpZ25lZFJlcXVlc3Qoe1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgaG9zdG5hbWU6IGJhc2VVcmwsXG4gICAgcGF0aDogXCIvYXBwLWNsaWVudHNcIixcbiAgICBib2R5OiBKU09OLnN0cmluZ2lmeShjbGllbnQpLFxuICB9KVxuXG4gIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgQ291bGQgbm90IGNyZWF0ZSByZXNvdXJjZTogJHtyZXNwb25zZS5zdGF0dXNDb2RlfSAtICR7cmVzcG9uc2UuYm9keX1gLFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLmJvZHkpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRBcHBDbGllbnQoXG4gIGJhc2VVcmw6IHN0cmluZyxcbiAgbmFtZTogc3RyaW5nLFxuKTogUHJvbWlzZTxBcHBDbGllbnQ+IHtcbiAgY29uc3QgZW5jb2RlZE5hbWUgPSBlbmNvZGVVUklDb21wb25lbnQobmFtZSlcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzaWduZWRSZXF1ZXN0KHtcbiAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgaG9zdG5hbWU6IGJhc2VVcmwsXG4gICAgcGF0aDogYC9hcHAtY2xpZW50cy8ke2VuY29kZWROYW1lfWAsXG4gIH0pXG5cbiAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBDb3VsZCBub3QgcmVhZCByZXNvdXJjZTogJHtyZXNwb25zZS5zdGF0dXNDb2RlfSAtICR7cmVzcG9uc2UuYm9keX1gLFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLmJvZHkpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZUFwcENsaWVudChcbiAgYmFzZVVybDogc3RyaW5nLFxuICB1cGRhdGU6IEFwcENsaWVudFVwZGF0ZVJlcXVlc3QsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgZW5jb2RlZE5hbWUgPSBlbmNvZGVVUklDb21wb25lbnQodXBkYXRlLm5hbWUpXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2lnbmVkUmVxdWVzdCh7XG4gICAgbWV0aG9kOiBcIlBVVFwiLFxuICAgIGhvc3RuYW1lOiBiYXNlVXJsLFxuICAgIHBhdGg6IGAvYXBwLWNsaWVudHMvJHtlbmNvZGVkTmFtZX1gLFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHVwZGF0ZSksXG4gIH0pXG5cbiAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBDb3VsZCBub3QgdXBkYXRlIHJlc291cmNlOiAke3Jlc3BvbnNlLnN0YXR1c0NvZGV9IC0gJHtyZXNwb25zZS5ib2R5fWAsXG4gICAgKVxuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRlbGV0ZUFwcENsaWVudChiYXNlVXJsOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBlbmNvZGVkTmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudChuYW1lKVxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNpZ25lZFJlcXVlc3Qoe1xuICAgIG1ldGhvZDogXCJERUxFVEVcIixcbiAgICBob3N0bmFtZTogYmFzZVVybCxcbiAgICBwYXRoOiBgL2FwcC1jbGllbnRzLyR7ZW5jb2RlZE5hbWV9YCxcbiAgfSlcblxuICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYENvdWxkIG5vdCBkZWxldGUgcmVzb3VyY2U6ICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX0gLSAke3Jlc3BvbnNlLmJvZHl9YCxcbiAgICApXG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoXG4gIGV2ZW50OiBDdXN0b21SZXNvdXJjZVJlcXVlc3QsXG4pOiBQcm9taXNlPEN1c3RvbVJlc291cmNlUmVzcG9uc2U+IHtcbiAgY29uc3QgcHJvcHMgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMgYXMgQXBwQ2xpZW50UHJvcGVydGllc1xuICBjb25zdCBiYXNlVXJsID0gY3JlYXRlVXJsRnJvbUVudmlyb25tZW50KFxuICAgIENPR05JVE9fQkFTRV9ET01BSU4sXG4gICAgXCJkZWxlZ2F0ZWRcIixcbiAgICBwcm9wcy5FbnZpcm9ubWVudCxcbiAgKVxuXG4gIHRyeSB7XG4gICAgc3dpdGNoIChldmVudC5SZXF1ZXN0VHlwZSkge1xuICAgICAgY2FzZSBcIkNyZWF0ZVwiOiB7XG4gICAgICAgIC8vIFdlIHJlY2VpdmUgYSBzdHJpbmcgdmFsdWUgZm9yIEdlbmVyYXRlU2VjcmV0LCBidXQgd2UgbmVlZCBhIGJvb2xlYW5cbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MtY2xvdWRmb3JtYXRpb24vY2xvdWRmb3JtYXRpb24tY292ZXJhZ2Utcm9hZG1hcC9pc3N1ZXMvMTAzN1xuICAgICAgICBjb25zdCBnZW5lcmF0ZV9zZWNyZXQ6IGJvb2xlYW4gPVxuICAgICAgICAgIHR5cGVvZiBwcm9wcy5HZW5lcmF0ZVNlY3JldCA9PT0gXCJib29sZWFuXCJcbiAgICAgICAgICAgID8gcHJvcHMuR2VuZXJhdGVTZWNyZXRcbiAgICAgICAgICAgIDogcHJvcHMuR2VuZXJhdGVTZWNyZXQgPT09IFwidHJ1ZVwiXG5cbiAgICAgICAgY29uc3QgY2xpZW50OiBBcHBDbGllbnQgPSB7XG4gICAgICAgICAgbmFtZTogcHJvcHMuTmFtZSxcbiAgICAgICAgICB0eXBlOiBwcm9wcy5UeXBlLFxuICAgICAgICAgIHNjb3BlczogcHJvcHMuU2NvcGVzIHx8IFtdLFxuICAgICAgICAgIGNhbGxiYWNrX3VybHM6IHByb3BzLkNhbGxiYWNrVXJscyB8fCBbXSxcbiAgICAgICAgICBsb2dvdXRfdXJsczogcHJvcHMuTG9nb3V0VXJscyB8fCBbXSxcbiAgICAgICAgICBnZW5lcmF0ZV9zZWNyZXQsXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjcmVhdGVkID0gYXdhaXQgY3JlYXRlQXBwQ2xpZW50KGJhc2VVcmwsIGNsaWVudClcblxuICAgICAgICByZXR1cm4gY3JlYXRlU3VjY2Vzc1Jlc3BvbnNlKGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCA/PyBjcmVhdGVkLm5hbWUsIHtcbiAgICAgICAgICBOYW1lOiBjcmVhdGVkLm5hbWUsXG4gICAgICAgICAgQ2xpZW50SWQ6IGNyZWF0ZWQuY2xpZW50X2lkIHx8IFwiXCIsXG4gICAgICAgICAgQ2xpZW50U2VjcmV0OiBjcmVhdGVkLmNsaWVudF9zZWNyZXQgfHwgXCJcIixcbiAgICAgICAgICBUeXBlOiBjcmVhdGVkLnR5cGUsXG4gICAgICAgIH0pIGFzIEN1c3RvbVJlc291cmNlUmVzcG9uc2VcbiAgICAgIH1cblxuICAgICAgY2FzZSBcIlVwZGF0ZVwiOiB7XG4gICAgICAgIC8vIENoZWNrIGlmIFR5cGUgY2hhbmdlZCAocmVxdWlyZXMgcmVwbGFjZW1lbnQpXG4gICAgICAgIGNvbnN0IG9sZFByb3BzID0gZXZlbnQuT2xkUmVzb3VyY2VQcm9wZXJ0aWVzIGFzIEFwcENsaWVudFByb3BlcnRpZXNcbiAgICAgICAgaWYgKG9sZFByb3BzICYmIG9sZFByb3BzLlR5cGUgIT09IHByb3BzLlR5cGUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBcIkNhbm5vdCBjaGFuZ2UgYXBwIGNsaWVudCB0eXBlLiBUaGlzIHJlcXVpcmVzIHJlc291cmNlIHJlcGxhY2VtZW50LlwiLFxuICAgICAgICAgIClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVwZGF0ZTogQXBwQ2xpZW50VXBkYXRlUmVxdWVzdCA9IHtcbiAgICAgICAgICBuYW1lOiBwcm9wcy5OYW1lLFxuICAgICAgICAgIHNjb3BlczogcHJvcHMuU2NvcGVzIHx8IFtdLFxuICAgICAgICAgIGNhbGxiYWNrX3VybHM6IHByb3BzLkNhbGxiYWNrVXJscyB8fCBbXSxcbiAgICAgICAgICBsb2dvdXRfdXJsczogcHJvcHMuTG9nb3V0VXJscyB8fCBbXSxcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHVwZGF0ZUFwcENsaWVudChiYXNlVXJsLCB1cGRhdGUpXG4gICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCByZWFkQXBwQ2xpZW50KGJhc2VVcmwsIHByb3BzLk5hbWUpXG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZVN1Y2Nlc3NSZXNwb25zZShldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPz8gdXBkYXRlZC5uYW1lLCB7XG4gICAgICAgICAgTmFtZTogdXBkYXRlZC5uYW1lLFxuICAgICAgICAgIENsaWVudElkOiB1cGRhdGVkLmNsaWVudF9pZCB8fCBcIlwiLFxuICAgICAgICAgIENsaWVudFNlY3JldDogdXBkYXRlZC5jbGllbnRfc2VjcmV0IHx8IFwiXCIsXG4gICAgICAgICAgVHlwZTogdXBkYXRlZC50eXBlLFxuICAgICAgICB9KSBhcyBDdXN0b21SZXNvdXJjZVJlc3BvbnNlXG4gICAgICB9XG5cbiAgICAgIGNhc2UgXCJEZWxldGVcIjoge1xuICAgICAgICBjb25zdCBuYW1lID0gZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkIHx8IHByb3BzLk5hbWVcbiAgICAgICAgYXdhaXQgZGVsZXRlQXBwQ2xpZW50KGJhc2VVcmwsIG5hbWUpXG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZVN1Y2Nlc3NSZXNwb25zZShuYW1lLCB7fSkgYXMgQ3VzdG9tUmVzb3VyY2VSZXNwb25zZVxuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKFwiRXJyb3I6XCIsIGVycm9yKVxuICAgIHJldHVybiBjcmVhdGVGYWlsdXJlUmVzcG9uc2UoXG4gICAgICBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfHwgcHJvcHMuTmFtZSB8fCBcInVua25vd25cIixcbiAgICAgIGhhbmRsZUVycm9yKGVycm9yKSxcbiAgICApIGFzIEN1c3RvbVJlc291cmNlUmVzcG9uc2VcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDK Construct for Cognito Info data source
|
|
3
|
+
*/
|
|
4
|
+
import { Construct } from "constructs";
|
|
5
|
+
import type { VyEnvironment } from "./shared/types";
|
|
6
|
+
export interface CognitoInfoProps {
|
|
7
|
+
/**
|
|
8
|
+
* The environment to get Cognito info for (e.g., VyEnvironment.PROD, VyEnvironment.STAGE, VyEnvironment.TEST)
|
|
9
|
+
*/
|
|
10
|
+
readonly environment: VyEnvironment;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Holds information about the centralized Cognito User Pool
|
|
14
|
+
*
|
|
15
|
+
* Use this to reference the shared Cognito User Pool in your CDK applications without
|
|
16
|
+
* hardcoding values.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const cognitoInfo = new CognitoInfo(this, 'CognitoInfo', {
|
|
21
|
+
* environment: VyEnvironment.PROD
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Access authentication endpoints
|
|
25
|
+
* console.log('Auth URL:', cognitoInfo.authUrl);
|
|
26
|
+
* console.log('JWKS URL:', cognitoInfo.jwksUrl);
|
|
27
|
+
* console.log('OpenID URL:', cognitoInfo.openIdUrl);
|
|
28
|
+
* console.log('Issuer:', cognitoInfo.issuer);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class CognitoInfo extends Construct {
|
|
32
|
+
/**
|
|
33
|
+
* The URL where users can authenticate
|
|
34
|
+
*/
|
|
35
|
+
readonly authUrl: string;
|
|
36
|
+
/**
|
|
37
|
+
* The URL for the /.well-known/jwks.json endpoint
|
|
38
|
+
*/
|
|
39
|
+
readonly jwksUrl: string;
|
|
40
|
+
/**
|
|
41
|
+
* The URL for the /.well-known/openid-configuration endpoint
|
|
42
|
+
*/
|
|
43
|
+
readonly openIdUrl: string;
|
|
44
|
+
/**
|
|
45
|
+
* The URI for the issuer
|
|
46
|
+
*/
|
|
47
|
+
readonly issuer: string;
|
|
48
|
+
constructor(scope: Construct, id: string, props: CognitoInfoProps);
|
|
49
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDK Construct for Cognito Info data source
|
|
3
|
+
*/
|
|
4
|
+
import { Construct } from "constructs";
|
|
5
|
+
/**
|
|
6
|
+
* Holds information about the centralized Cognito User Pool
|
|
7
|
+
*
|
|
8
|
+
* Use this to reference the shared Cognito User Pool in your CDK applications without
|
|
9
|
+
* hardcoding values.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const cognitoInfo = new CognitoInfo(this, 'CognitoInfo', {
|
|
14
|
+
* environment: VyEnvironment.PROD
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* // Access authentication endpoints
|
|
18
|
+
* console.log('Auth URL:', cognitoInfo.authUrl);
|
|
19
|
+
* console.log('JWKS URL:', cognitoInfo.jwksUrl);
|
|
20
|
+
* console.log('OpenID URL:', cognitoInfo.openIdUrl);
|
|
21
|
+
* console.log('Issuer:', cognitoInfo.issuer);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class CognitoInfo extends Construct {
|
|
25
|
+
/**
|
|
26
|
+
* The URL where users can authenticate
|
|
27
|
+
*/
|
|
28
|
+
authUrl;
|
|
29
|
+
/**
|
|
30
|
+
* The URL for the /.well-known/jwks.json endpoint
|
|
31
|
+
*/
|
|
32
|
+
jwksUrl;
|
|
33
|
+
/**
|
|
34
|
+
* The URL for the /.well-known/openid-configuration endpoint
|
|
35
|
+
*/
|
|
36
|
+
openIdUrl;
|
|
37
|
+
/**
|
|
38
|
+
* The URI for the issuer
|
|
39
|
+
*/
|
|
40
|
+
issuer;
|
|
41
|
+
constructor(scope, id, props) {
|
|
42
|
+
super(scope, id);
|
|
43
|
+
this.authUrl = getCognitoInfo(props.environment).authUrl;
|
|
44
|
+
this.jwksUrl = getCognitoInfo(props.environment).jwksUrl;
|
|
45
|
+
this.openIdUrl = getCognitoInfo(props.environment).openIdUrl;
|
|
46
|
+
this.issuer = getCognitoInfo(props.environment).issuer;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function getCognitoInfo(environment) {
|
|
50
|
+
const envConfigs = {
|
|
51
|
+
prod: {
|
|
52
|
+
authUrl: "https://auth.cognito.vydev.io",
|
|
53
|
+
jwksUrl: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_e6o46c1oE/.well-known/jwks.json",
|
|
54
|
+
openIdUrl: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_e6o46c1oE/.well-known/openid-configuration",
|
|
55
|
+
issuer: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_e6o46c1oE",
|
|
56
|
+
},
|
|
57
|
+
stage: {
|
|
58
|
+
authUrl: "https://auth.stage.cognito.vydev.io",
|
|
59
|
+
jwksUrl: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_AUYQ679zW/.well-known/jwks.json",
|
|
60
|
+
openIdUrl: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_AUYQ679zW/.well-known/openid-configuration",
|
|
61
|
+
issuer: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_AUYQ679zW",
|
|
62
|
+
},
|
|
63
|
+
test: {
|
|
64
|
+
authUrl: "https://auth.test.cognito.vydev.io",
|
|
65
|
+
jwksUrl: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_Z53b9AbeT/.well-known/jwks.json",
|
|
66
|
+
openIdUrl: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_Z53b9AbeT/.well-known/openid-configuration",
|
|
67
|
+
issuer: "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_Z53b9AbeT",
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const config = envConfigs[environment];
|
|
71
|
+
if (!config) {
|
|
72
|
+
throw new Error(`Unknown environment: ${environment}. Valid values are: prod, stage, test, dev`);
|
|
73
|
+
}
|
|
74
|
+
return config;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29nbml0by1pbmZvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvZ25pdG8taW5mby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFVdEM7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILE1BQU0sT0FBTyxXQUFZLFNBQVEsU0FBUztJQUN4Qzs7T0FFRztJQUNhLE9BQU8sQ0FBUTtJQUUvQjs7T0FFRztJQUNhLE9BQU8sQ0FBUTtJQUUvQjs7T0FFRztJQUNhLFNBQVMsQ0FBUTtJQUVqQzs7T0FFRztJQUNhLE1BQU0sQ0FBUTtJQUU5QixZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXVCO1FBQy9ELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQTtRQUN4RCxJQUFJLENBQUMsT0FBTyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFBO1FBQ3hELElBQUksQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxTQUFTLENBQUE7UUFDNUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQTtJQUN4RCxDQUFDO0NBQ0Y7QUFFRCxTQUFTLGNBQWMsQ0FBQyxXQUFtQjtJQUN6QyxNQUFNLFVBQVUsR0FBbUM7UUFDakQsSUFBSSxFQUFFO1lBQ0osT0FBTyxFQUFFLCtCQUErQjtZQUN4QyxPQUFPLEVBQ0wsdUZBQXVGO1lBQ3pGLFNBQVMsRUFDUCxrR0FBa0c7WUFDcEcsTUFBTSxFQUFFLGlFQUFpRTtTQUMxRTtRQUNELEtBQUssRUFBRTtZQUNMLE9BQU8sRUFBRSxxQ0FBcUM7WUFDOUMsT0FBTyxFQUNMLHVGQUF1RjtZQUN6RixTQUFTLEVBQ1Asa0dBQWtHO1lBQ3BHLE1BQU0sRUFBRSxpRUFBaUU7U0FDMUU7UUFDRCxJQUFJLEVBQUU7WUFDSixPQUFPLEVBQUUsb0NBQW9DO1lBQzdDLE9BQU8sRUFDTCx1RkFBdUY7WUFDekYsU0FBUyxFQUNQLGtHQUFrRztZQUNwRyxNQUFNLEVBQUUsaUVBQWlFO1NBQzFFO0tBQ0YsQ0FBQTtJQUVELE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQTtJQUN0QyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLElBQUksS0FBSyxDQUNiLHdCQUF3QixXQUFXLDRDQUE0QyxDQUNoRixDQUFBO0lBQ0gsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFBO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ0RLIENvbnN0cnVjdCBmb3IgQ29nbml0byBJbmZvIGRhdGEgc291cmNlXG4gKi9cblxuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIlxuaW1wb3J0IHR5cGUgeyBDb2duaXRvRGV0YWlscywgVnlFbnZpcm9ubWVudCB9IGZyb20gXCIuL3NoYXJlZC90eXBlc1wiXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29nbml0b0luZm9Qcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgZW52aXJvbm1lbnQgdG8gZ2V0IENvZ25pdG8gaW5mbyBmb3IgKGUuZy4sIFZ5RW52aXJvbm1lbnQuUFJPRCwgVnlFbnZpcm9ubWVudC5TVEFHRSwgVnlFbnZpcm9ubWVudC5URVNUKVxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ6IFZ5RW52aXJvbm1lbnRcbn1cblxuLyoqXG4gKiBIb2xkcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY2VudHJhbGl6ZWQgQ29nbml0byBVc2VyIFBvb2xcbiAqXG4gKiBVc2UgdGhpcyB0byByZWZlcmVuY2UgdGhlIHNoYXJlZCBDb2duaXRvIFVzZXIgUG9vbCBpbiB5b3VyIENESyBhcHBsaWNhdGlvbnMgd2l0aG91dFxuICogaGFyZGNvZGluZyB2YWx1ZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNvZ25pdG9JbmZvID0gbmV3IENvZ25pdG9JbmZvKHRoaXMsICdDb2duaXRvSW5mbycsIHtcbiAqICAgZW52aXJvbm1lbnQ6IFZ5RW52aXJvbm1lbnQuUFJPRFxuICogfSk7XG4gKlxuICogLy8gQWNjZXNzIGF1dGhlbnRpY2F0aW9uIGVuZHBvaW50c1xuICogY29uc29sZS5sb2coJ0F1dGggVVJMOicsIGNvZ25pdG9JbmZvLmF1dGhVcmwpO1xuICogY29uc29sZS5sb2coJ0pXS1MgVVJMOicsIGNvZ25pdG9JbmZvLmp3a3NVcmwpO1xuICogY29uc29sZS5sb2coJ09wZW5JRCBVUkw6JywgY29nbml0b0luZm8ub3BlbklkVXJsKTtcbiAqIGNvbnNvbGUubG9nKCdJc3N1ZXI6JywgY29nbml0b0luZm8uaXNzdWVyKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgQ29nbml0b0luZm8gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIFVSTCB3aGVyZSB1c2VycyBjYW4gYXV0aGVudGljYXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXV0aFVybDogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBVUkwgZm9yIHRoZSAvLndlbGwta25vd24vandrcy5qc29uIGVuZHBvaW50XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgandrc1VybDogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBVUkwgZm9yIHRoZSAvLndlbGwta25vd24vb3BlbmlkLWNvbmZpZ3VyYXRpb24gZW5kcG9pbnRcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBvcGVuSWRVcmw6IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBUaGUgVVJJIGZvciB0aGUgaXNzdWVyXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXNzdWVyOiBzdHJpbmdcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ29nbml0b0luZm9Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIHRoaXMuYXV0aFVybCA9IGdldENvZ25pdG9JbmZvKHByb3BzLmVudmlyb25tZW50KS5hdXRoVXJsXG4gICAgdGhpcy5qd2tzVXJsID0gZ2V0Q29nbml0b0luZm8ocHJvcHMuZW52aXJvbm1lbnQpLmp3a3NVcmxcbiAgICB0aGlzLm9wZW5JZFVybCA9IGdldENvZ25pdG9JbmZvKHByb3BzLmVudmlyb25tZW50KS5vcGVuSWRVcmxcbiAgICB0aGlzLmlzc3VlciA9IGdldENvZ25pdG9JbmZvKHByb3BzLmVudmlyb25tZW50KS5pc3N1ZXJcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRDb2duaXRvSW5mbyhlbnZpcm9ubWVudDogc3RyaW5nKTogQ29nbml0b0RldGFpbHMge1xuICBjb25zdCBlbnZDb25maWdzOiBSZWNvcmQ8c3RyaW5nLCBDb2duaXRvRGV0YWlscz4gPSB7XG4gICAgcHJvZDoge1xuICAgICAgYXV0aFVybDogXCJodHRwczovL2F1dGguY29nbml0by52eWRldi5pb1wiLFxuICAgICAgandrc1VybDpcbiAgICAgICAgXCJodHRwczovL2NvZ25pdG8taWRwLmV1LXdlc3QtMS5hbWF6b25hd3MuY29tL2V1LXdlc3QtMV9lNm80NmMxb0UvLndlbGwta25vd24vandrcy5qc29uXCIsXG4gICAgICBvcGVuSWRVcmw6XG4gICAgICAgIFwiaHR0cHM6Ly9jb2duaXRvLWlkcC5ldS13ZXN0LTEuYW1hem9uYXdzLmNvbS9ldS13ZXN0LTFfZTZvNDZjMW9FLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uXCIsXG4gICAgICBpc3N1ZXI6IFwiaHR0cHM6Ly9jb2duaXRvLWlkcC5ldS13ZXN0LTEuYW1hem9uYXdzLmNvbS9ldS13ZXN0LTFfZTZvNDZjMW9FXCIsXG4gICAgfSxcbiAgICBzdGFnZToge1xuICAgICAgYXV0aFVybDogXCJodHRwczovL2F1dGguc3RhZ2UuY29nbml0by52eWRldi5pb1wiLFxuICAgICAgandrc1VybDpcbiAgICAgICAgXCJodHRwczovL2NvZ25pdG8taWRwLmV1LXdlc3QtMS5hbWF6b25hd3MuY29tL2V1LXdlc3QtMV9BVVlRNjc5elcvLndlbGwta25vd24vandrcy5qc29uXCIsXG4gICAgICBvcGVuSWRVcmw6XG4gICAgICAgIFwiaHR0cHM6Ly9jb2duaXRvLWlkcC5ldS13ZXN0LTEuYW1hem9uYXdzLmNvbS9ldS13ZXN0LTFfQVVZUTY3OXpXLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uXCIsXG4gICAgICBpc3N1ZXI6IFwiaHR0cHM6Ly9jb2duaXRvLWlkcC5ldS13ZXN0LTEuYW1hem9uYXdzLmNvbS9ldS13ZXN0LTFfQVVZUTY3OXpXXCIsXG4gICAgfSxcbiAgICB0ZXN0OiB7XG4gICAgICBhdXRoVXJsOiBcImh0dHBzOi8vYXV0aC50ZXN0LmNvZ25pdG8udnlkZXYuaW9cIixcbiAgICAgIGp3a3NVcmw6XG4gICAgICAgIFwiaHR0cHM6Ly9jb2duaXRvLWlkcC5ldS13ZXN0LTEuYW1hem9uYXdzLmNvbS9ldS13ZXN0LTFfWjUzYjlBYmVULy53ZWxsLWtub3duL2p3a3MuanNvblwiLFxuICAgICAgb3BlbklkVXJsOlxuICAgICAgICBcImh0dHBzOi8vY29nbml0by1pZHAuZXUtd2VzdC0xLmFtYXpvbmF3cy5jb20vZXUtd2VzdC0xX1o1M2I5QWJlVC8ud2VsbC1rbm93bi9vcGVuaWQtY29uZmlndXJhdGlvblwiLFxuICAgICAgaXNzdWVyOiBcImh0dHBzOi8vY29nbml0by1pZHAuZXUtd2VzdC0xLmFtYXpvbmF3cy5jb20vZXUtd2VzdC0xX1o1M2I5QWJlVFwiLFxuICAgIH0sXG4gIH1cblxuICBjb25zdCBjb25maWcgPSBlbnZDb25maWdzW2Vudmlyb25tZW50XVxuICBpZiAoIWNvbmZpZykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBVbmtub3duIGVudmlyb25tZW50OiAke2Vudmlyb25tZW50fS4gVmFsaWQgdmFsdWVzIGFyZTogcHJvZCwgc3RhZ2UsIHRlc3QsIGRldmAsXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGNvbmZpZ1xufVxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "jest-cdk-snapshot";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { App, Stack } from "aws-cdk-lib";
|
|
2
|
+
import "jest-cdk-snapshot";
|
|
3
|
+
import { VyEnvironment } from "../../shared/types";
|
|
4
|
+
import { CognitoResourceServer } from "../cognito-resource-server";
|
|
5
|
+
test("cognito resource server", () => {
|
|
6
|
+
const app = new App();
|
|
7
|
+
const stack = new Stack(app, "Stack");
|
|
8
|
+
new CognitoResourceServer(stack, "CognitoResourceServer", {
|
|
9
|
+
environment: VyEnvironment.TEST,
|
|
10
|
+
name: "testName",
|
|
11
|
+
identifier: "testIdentifier",
|
|
12
|
+
scopes: [
|
|
13
|
+
{
|
|
14
|
+
name: "testScopeName",
|
|
15
|
+
description: "testScopeDescription",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
});
|
|
19
|
+
expect(stack).toMatchCdkSnapshot({
|
|
20
|
+
ignoreAssets: true,
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb2duaXRvLXJlc291cmNlLXNlcnZlci9fX3Rlc3RfXy9pbmRleC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3hDLE9BQU8sbUJBQW1CLENBQUE7QUFDMUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFBO0FBRWxFLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxHQUFHLEVBQUU7SUFDbkMsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUNyQixNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFFckMsSUFBSSxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLEVBQUU7UUFDeEQsV0FBVyxFQUFFLGFBQWEsQ0FBQyxJQUFJO1FBQy9CLElBQUksRUFBRSxVQUFVO1FBQ2hCLFVBQVUsRUFBRSxnQkFBZ0I7UUFDNUIsTUFBTSxFQUFFO1lBQ047Z0JBQ0UsSUFBSSxFQUFFLGVBQWU7Z0JBQ3JCLFdBQVcsRUFBRSxzQkFBc0I7YUFDcEM7U0FDRjtLQUNGLENBQUMsQ0FBQTtJQUVGLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixZQUFZLEVBQUUsSUFBSTtLQUNuQixDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFwcCwgU3RhY2sgfSBmcm9tIFwiYXdzLWNkay1saWJcIlxuaW1wb3J0IFwiamVzdC1jZGstc25hcHNob3RcIlxuaW1wb3J0IHsgVnlFbnZpcm9ubWVudCB9IGZyb20gXCIuLi8uLi9zaGFyZWQvdHlwZXNcIlxuaW1wb3J0IHsgQ29nbml0b1Jlc291cmNlU2VydmVyIH0gZnJvbSBcIi4uL2NvZ25pdG8tcmVzb3VyY2Utc2VydmVyXCJcblxudGVzdChcImNvZ25pdG8gcmVzb3VyY2Ugc2VydmVyXCIsICgpID0+IHtcbiAgY29uc3QgYXBwID0gbmV3IEFwcCgpXG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKGFwcCwgXCJTdGFja1wiKVxuXG4gIG5ldyBDb2duaXRvUmVzb3VyY2VTZXJ2ZXIoc3RhY2ssIFwiQ29nbml0b1Jlc291cmNlU2VydmVyXCIsIHtcbiAgICBlbnZpcm9ubWVudDogVnlFbnZpcm9ubWVudC5URVNULFxuICAgIG5hbWU6IFwidGVzdE5hbWVcIixcbiAgICBpZGVudGlmaWVyOiBcInRlc3RJZGVudGlmaWVyXCIsXG4gICAgc2NvcGVzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6IFwidGVzdFNjb3BlTmFtZVwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJ0ZXN0U2NvcGVEZXNjcmlwdGlvblwiLFxuICAgICAgfSxcbiAgICBdLFxuICB9KVxuXG4gIGV4cGVjdChzdGFjaykudG9NYXRjaENka1NuYXBzaG90KHtcbiAgICBpZ25vcmVBc3NldHM6IHRydWUsXG4gIH0pXG59KVxuIl19
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDK Construct for Cognito Resource Server
|
|
3
|
+
*/
|
|
4
|
+
import * as cdk from "aws-cdk-lib";
|
|
5
|
+
import * as logs from "aws-cdk-lib/aws-logs";
|
|
6
|
+
import { Construct } from "constructs";
|
|
7
|
+
import type { VyEnvironment } from "../shared/types";
|
|
8
|
+
export interface Scope {
|
|
9
|
+
/**
|
|
10
|
+
* The name of the scope
|
|
11
|
+
*/
|
|
12
|
+
readonly name: string;
|
|
13
|
+
/**
|
|
14
|
+
* A description of what this scope is for
|
|
15
|
+
*/
|
|
16
|
+
readonly description: string;
|
|
17
|
+
}
|
|
18
|
+
export interface CognitoResourceServerProps {
|
|
19
|
+
/**
|
|
20
|
+
* The Vy environment to provision in (e.g., VyEnvironment.PROD, VyEnvironment.STAGE, VyEnvironment.TEST)
|
|
21
|
+
*/
|
|
22
|
+
readonly environment: VyEnvironment;
|
|
23
|
+
/**
|
|
24
|
+
* The name of the resource server
|
|
25
|
+
*/
|
|
26
|
+
readonly name: string;
|
|
27
|
+
/**
|
|
28
|
+
* The identifier for this resource server (usually a URL)
|
|
29
|
+
* @example 'https://api.vydev.io'
|
|
30
|
+
*/
|
|
31
|
+
readonly identifier: string;
|
|
32
|
+
/**
|
|
33
|
+
* Custom scopes for this resource server
|
|
34
|
+
* @default - No scopes
|
|
35
|
+
*/
|
|
36
|
+
readonly scopes?: Scope[];
|
|
37
|
+
/**
|
|
38
|
+
* Base domain for Cognito service
|
|
39
|
+
* @default 'cognito.vydev.io'
|
|
40
|
+
*/
|
|
41
|
+
readonly cognitoBaseDomain?: string;
|
|
42
|
+
/**
|
|
43
|
+
* @default logs.RetentionDays.ONE_WEEK
|
|
44
|
+
*/
|
|
45
|
+
readonly logsRetention?: logs.RetentionDays;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A Cognito Resource Server managed through Vy's central Cognito service
|
|
49
|
+
*
|
|
50
|
+
* A resource server is an integration between a user pool and an API.
|
|
51
|
+
* Each resource server has custom scopes that you must activate in your app client.
|
|
52
|
+
* When you configure a resource server, your app can generate access tokens with
|
|
53
|
+
* OAuth scopes that authorize read and write operations to an API server.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const resourceServer = new CognitoResourceServer(this, 'ApiResourceServer', {
|
|
58
|
+
* environment: VyEnvironment.PROD,
|
|
59
|
+
* name: 'my-api',
|
|
60
|
+
* identifier: 'https://my-api.vydev.io',
|
|
61
|
+
* scopes: [
|
|
62
|
+
* { name: 'read', description: 'Read access to the API' },
|
|
63
|
+
* { name: 'write', description: 'Write access to the API' }
|
|
64
|
+
* ]
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare class CognitoResourceServer extends Construct {
|
|
69
|
+
/**
|
|
70
|
+
* The identifier of the resource server
|
|
71
|
+
*/
|
|
72
|
+
readonly identifier: string;
|
|
73
|
+
/**
|
|
74
|
+
* The name of the resource server
|
|
75
|
+
*/
|
|
76
|
+
readonly name: string;
|
|
77
|
+
/**
|
|
78
|
+
* The underlying custom resource
|
|
79
|
+
*/
|
|
80
|
+
readonly resource: cdk.CustomResource;
|
|
81
|
+
/**
|
|
82
|
+
* The logGroup for the event handler lambda
|
|
83
|
+
*/
|
|
84
|
+
readonly lambdaLogGroup: logs.LogGroup;
|
|
85
|
+
/**
|
|
86
|
+
* The logGroup for the custom resource provider
|
|
87
|
+
*/
|
|
88
|
+
readonly providerLogGroup: logs.LogGroup;
|
|
89
|
+
constructor(scope: Construct, id: string, props: CognitoResourceServerProps);
|
|
90
|
+
/**
|
|
91
|
+
* Get a reference to a scope in the format expected by app clients
|
|
92
|
+
* @param scopeName The name of the scope
|
|
93
|
+
* @returns The full scope identifier (e.g., 'https://api.vydev.io/read')
|
|
94
|
+
*/
|
|
95
|
+
scopeIdentifier(scopeName: string): string;
|
|
96
|
+
}
|