Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
constructor(parent: cdk.App, id: string, props?: cdk.StackProps) {
super(parent, id, props)
const lambdaName = `${pkg.name}-handler`
const lambdaParams: lambda.FunctionProps = {
code: lambda.Code.asset('.'),
description: 'universal route',
functionName: lambdaName,
handler: 'dist/assets/backend/lambda.handler',
runtime: lambda.Runtime.NodeJS810,
}
const fn = new lambda.Function(this, lambdaName, lambdaParams)
const apiGateway = new api.RestApi(this, `${pkg.name}-api-gateway`, {
binaryMediaTypes: ['*/*'],
})
const defaultIntegration = new api.LambdaIntegration(fn)
apiGateway.root.addMethod('GET', defaultIntegration)
const proxy = apiGateway.root.addResource('{any+}')
proxy.addMethod('GET', defaultIntegration)
const role = new iam.Role(this, `${pkg.name}-Role`, {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
})
// TODO: PLEASE! PLEASE! WORK THIS OVER!!! this could be a viable security breach.
role.addToPolicy(
new iam.PolicyStatement()
.addAllResources()
.addActions(
'sts:AssumeRole',
public constructor(parent: App, name: string, props?: StackProps) {
super(parent, name, props);
const api = new RestApi(this, 'github-webhook');
api.root.addMethod('POST');
const githubApiToken = process.env.API_TOKEN as string;
// @example https://github.com/cloudcomponents/cdk-components
const githubRepoUrl = process.env.REPO_URL as string;
// @see https://developer.github.com/v3/activity/events/types/
const events = ['*'];
new GithubWebhook(this, 'GithubWebhook', {
githubApiToken,
githubRepoUrl,
payloadUrl: api.url,
events,
logLevel: 'debug',
super(parent, id, props)
const lambdaName = `${pkg.name}-handler`
const lambdaParams: lambda.FunctionProps = {
code: lambda.Code.asset('.'),
description: 'universal route',
functionName: lambdaName,
handler: 'dist/assets/backend/lambda.handler',
runtime: lambda.Runtime.NodeJS810,
}
const fn = new lambda.Function(this, lambdaName, lambdaParams)
const apiGateway = new api.RestApi(this, `${pkg.name}-api-gateway`, {
binaryMediaTypes: ['*/*'],
})
const defaultIntegration = new api.LambdaIntegration(fn)
apiGateway.root.addMethod('GET', defaultIntegration)
const proxy = apiGateway.root.addResource('{any+}')
proxy.addMethod('GET', defaultIntegration)
const role = new iam.Role(this, `${pkg.name}-Role`, {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
})
// TODO: PLEASE! PLEASE! WORK THIS OVER!!! this could be a viable security breach.
role.addToPolicy(
new iam.PolicyStatement()
.addAllResources()
.addActions(
'sts:AssumeRole',
'logs:CreateLogStream',
'logs:PutLogEvents',
'lambda:InvokeFunction',
'lambda:InvokeAsync'
// ------------------------------------------------------------------------
const api = new apigateway.RestApi(this, id + "API");
const integration = new apigateway.LambdaIntegration(apiFunction, {
// lambda proxy integration:
// see https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-create-api-as-simple-proxy
proxy: true
});
// ------------------------------------------------------------------------
// Cognito Authorizer
// ------------------------------------------------------------------------
const cfnAuthorizer = new apigateway.CfnAuthorizer(this, id, {
name: "CognitoAuthorizer",
type: AuthorizationType.COGNITO,
identitySource: "method.request.header." + authorizationHeaderName,
restApiId: api.restApiId,
providerArns: [userPool.userPoolArn]
});
// ------------------------------------------------------------------------
// Root (/) - no authorization required
// ------------------------------------------------------------------------
const rootResource = api.root;
rootResource.addMethod("ANY", integration);
// ------------------------------------------------------------------------
// All Other Paths (/{proxy+}) - authorization required
const rootResource = api.root;
rootResource.addMethod("ANY", integration);
// ------------------------------------------------------------------------
// All Other Paths (/{proxy+}) - authorization required
// ------------------------------------------------------------------------
// all other paths require the cognito authorizer (validates the JWT and passes it to the lambda)
const proxyResource = rootResource.addResource("{proxy+}");
const method = proxyResource.addMethod("ANY", integration, {
authorizer: {authorizerId: cfnAuthorizer.ref},
authorizationType: AuthorizationType.COGNITO,
});
// uncomment to use an access token instead of an id token
// const cfnMethod = method.node.defaultChild as apigateway.CfnMethod;
// cfnMethod.authorizationScopes = ["openid"];
// ------------------------------------------------------------------------
// Add CORS support to all
// ------------------------------------------------------------------------
Utils.addCorsOptions(proxyResource, corsOrigin);
Utils.addCorsOptions(rootResource, corsOrigin);
// ========================================================================
description: 'api key for general api route',
enabled: true,
generateDistinctId: true,
name: `${name}-api-key`,
stageKeys: [
{ restApiId: new Token(this.apiGateway.restApiId), stageName: 'prod' },
],
}
const usagePlanConfig = {
apiStages: [
{ apiId: new Token(this.apiGateway.restApiId), stage: 'prod' },
],
description: 'universal plan to secure the api gateway',
usagePlanName: 'universal plan',
}
const apiKey = new CfnApiKey(this, 'lambdaApiKey', apiKeyConfig)
const usagePlan = new CfnUsagePlan(this, 'usagePlan', usagePlanConfig)
const usageKeyConfig = {
keyId: new Token(apiKey.apiKeyId),
keyType: 'API_KEY',
usagePlanId: new Token(usagePlan.usagePlanId),
}
// tslint:disable-next-line:no-unused-expression
new CfnUsagePlanKey(this, 'usageKey', usageKeyConfig)
const proxy = this.apiGateway.root.addResource('{any+}')
this.apiGateway.root.addMethod('GET', this.defaultIntegration, {
apiKeyRequired: true,
})
this.apiGateway.root.addMethod('POST', this.defaultIntegration, {
apiKeyRequired: true,
})
enabled: true,
generateDistinctId: true,
name: `${name}-api-key`,
stageKeys: [
{ restApiId: new Token(this.apiGateway.restApiId), stageName: 'prod' },
],
}
const usagePlanConfig = {
apiStages: [
{ apiId: new Token(this.apiGateway.restApiId), stage: 'prod' },
],
description: 'universal plan to secure the api gateway',
usagePlanName: 'universal plan',
}
const apiKey = new CfnApiKey(this, 'lambdaApiKey', apiKeyConfig)
const usagePlan = new CfnUsagePlan(this, 'usagePlan', usagePlanConfig)
const usageKeyConfig = {
keyId: new Token(apiKey.apiKeyId),
keyType: 'API_KEY',
usagePlanId: new Token(usagePlan.usagePlanId),
}
// tslint:disable-next-line:no-unused-expression
new CfnUsagePlanKey(this, 'usageKey', usageKeyConfig)
const proxy = this.apiGateway.root.addResource('{any+}')
this.apiGateway.root.addMethod('GET', this.defaultIntegration, {
apiKeyRequired: true,
})
this.apiGateway.root.addMethod('POST', this.defaultIntegration, {
apiKeyRequired: true,
})
this.apiGateway.root.addMethod('DELETE', this.defaultIntegration, {
const usagePlanConfig = {
apiStages: [
{ apiId: new Token(this.apiGateway.restApiId), stage: 'prod' },
],
description: 'universal plan to secure the api gateway',
usagePlanName: 'universal plan',
}
const apiKey = new CfnApiKey(this, 'lambdaApiKey', apiKeyConfig)
const usagePlan = new CfnUsagePlan(this, 'usagePlan', usagePlanConfig)
const usageKeyConfig = {
keyId: new Token(apiKey.apiKeyId),
keyType: 'API_KEY',
usagePlanId: new Token(usagePlan.usagePlanId),
}
// tslint:disable-next-line:no-unused-expression
new CfnUsagePlanKey(this, 'usageKey', usageKeyConfig)
const proxy = this.apiGateway.root.addResource('{any+}')
this.apiGateway.root.addMethod('GET', this.defaultIntegration, {
apiKeyRequired: true,
})
this.apiGateway.root.addMethod('POST', this.defaultIntegration, {
apiKeyRequired: true,
})
this.apiGateway.root.addMethod('DELETE', this.defaultIntegration, {
apiKeyRequired: true,
})
proxy.addMethod('GET', this.defaultIntegration, { apiKeyRequired: true })
proxy.addMethod('POST', this.defaultIntegration, { apiKeyRequired: true })
proxy.addMethod('DELETE', this.defaultIntegration, { apiKeyRequired: true })
this.apiGatewayDomain = getApiGatewayDomain(this.apiGateway.url)
this.apiGatewayOriginPath = getApiGatewayPath(this.apiGateway.url)
super(parent, id, props);
// Create a lambda that returns autocomplete results
const autocomplete = new lambda.Function(this, 'autocomplete', {
runtime: lambda.Runtime.NODEJS_10_X,
handler: 'autocomplete.handle',
code: lambda.Code.asset('./app/autocomplete'),
environment: {
SEARCH_INDEX_TABLE_NAME: props.searchIndexTable.tableName
}
});
// Grant the lambda permission to modify the tables
props.searchIndexTable.grantReadWriteData(autocomplete.role);
this.autocompleteGateway = new apiGateway.LambdaRestApi(this, 'autocomplete-gateway', {
handler: autocomplete,
proxy: true
});
this.url = this.autocompleteGateway.url;
}
}
[fqdn]: (): api.RestApiProps => ({
binaryMediaTypes: MediaTypes(props),
deploy: true,
deployOptions: {
stageName: (props.sites && props.sites.length > 0) ? props.sites[0].site.split('/')[0] : 'api'
},
domainName: {
certificate,
domainName: site(props),
},
endpointTypes: [api.EndpointType.REGIONAL],
failOnWarnings: true,
})
}