Skip to content

Commit

Permalink
Initial app
Browse files Browse the repository at this point in the history
  • Loading branch information
ggalmeida0 committed May 29, 2023
0 parents commit c1b283d
Show file tree
Hide file tree
Showing 38 changed files with 31,578 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Service
service/node_modules
service/lambda
service/dist

# Infra
infra/*.js
!infra/jest.config.js
infra/*.d.ts
infra/node_modules

# CDK asset staging directory
.cdk.staging
cdk.out

# UI
ui/node_modules/
ui/.expo/
ui/dist/
ui/npm-debug.*
ui/*.jks
ui/*.p8
ui/*.p12
ui/*.key
ui/*.mobileprovision
ui/*.orig.*
ui/web-build/

# macOS
.DS_Store

# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
6 changes: 6 additions & 0 deletions infra/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.ts
!*.d.ts

# CDK asset staging directory
.cdk.staging
cdk.out
14 changes: 14 additions & 0 deletions infra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Welcome to your CDK TypeScript project

This is a blank project for CDK development with TypeScript.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
7 changes: 7 additions & 0 deletions infra/bin/bio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { BioStack } from '../lib/bio-stack';

const app = new cdk.App();
new BioStack(app, 'BioStack');
53 changes: 53 additions & 0 deletions infra/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"app": "npx ts-node --prefer-ts-exts bin/bio.ts",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
"@aws-cdk/aws-redshift:columnId": true,
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true
}
}
8 changes: 8 additions & 0 deletions infra/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/test'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest'
}
};
141 changes: 141 additions & 0 deletions infra/lib/bio-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import * as cdk from 'aws-cdk-lib';
import { UserPoolClientIdentityProvider } from 'aws-cdk-lib/aws-cognito';
import { Construct } from 'constructs';
import {
CorsHttpMethod,
HttpApi,
HttpMethod,
} from '@aws-cdk/aws-apigatewayv2-alpha';
import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations-alpha';
import { HttpJwtAuthorizer } from '@aws-cdk/aws-apigatewayv2-authorizers-alpha';
import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';

export class BioStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const { userPool, client } = this.setupAuth();
this.setupDatabase();
this.setupService(userPool, client);
}

setupDatabase() {
new cdk.aws_dynamodb.Table(this, 'UserChats', {
tableName: 'UserChats',
partitionKey: {
name: 'userId',
type: cdk.aws_dynamodb.AttributeType.STRING,
},
sortKey: {
name: 'date',
type: cdk.aws_dynamodb.AttributeType.STRING,
},
billingMode: cdk.aws_dynamodb.BillingMode.PAY_PER_REQUEST,
});
}

setupService(
userPool: cdk.aws_cognito.UserPool,
client: cdk.aws_cognito.UserPoolClient
) {
const lambda = new cdk.aws_lambda.Function(this, 'BioService', {
functionName: 'BioService',
runtime: cdk.aws_lambda.Runtime.NODEJS_18_X,
handler: 'dist/handler.handler',
code: cdk.aws_lambda.Code.fromAsset('../service/lambda/bio-service.zip'),
initialPolicy: [
PolicyStatement.fromJson({
Effect: Effect.ALLOW,
Action: ['dynamodb:Query', 'dynamodb:UpdateItem'],
Resource: 'arn:aws:dynamodb:*:*:table/UserChats',
}),
],
timeout: cdk.Duration.seconds(30),
});

const openAiApiKey = cdk.aws_secretsmanager.Secret.fromSecretNameV2(
this,
'OPENAI_API_KEY',
'prod/bio'
);

openAiApiKey.grantRead(lambda);

const api = new HttpApi(this, 'BioAPI', {
apiName: 'BioAPI',
corsPreflight: {
allowHeaders: ['*'],
allowMethods: [CorsHttpMethod.GET, CorsHttpMethod.POST],
allowOrigins: ['http://localhost:19006'],
maxAge: cdk.Duration.days(7),
},
});

const authorizer = new HttpJwtAuthorizer(
'APIAuthorizer',
`https://cognito-idp.${this.region}.amazonaws.com/${userPool.userPoolId}`,
{
identitySource: ['$request.header.Authorization'],
jwtAudience: [client.userPoolClientId],
}
);

const getChatIntegration = new HttpLambdaIntegration(
'APIIntegration::getChat',
lambda
);
const sendChatIntegration = new HttpLambdaIntegration(
'APIIntegration::sendChat',
lambda
);

api.addRoutes({
path: '/getChat',
methods: [HttpMethod.GET],
integration: getChatIntegration,
authorizer,
});
api.addRoutes({
path: '/sendChat',
methods: [HttpMethod.POST],
integration: sendChatIntegration,
authorizer,
});
}

setupAuth() {
const googleClientSecret = cdk.SecretValue.secretsManager('prod/bio', {
jsonField: 'BIO_GOOGLE_OAUTH_CLIENT_SECRET',
});

const userPool = new cdk.aws_cognito.UserPool(this, 'BioUserPool', {
userPoolName: 'BioUserPool',
});

userPool.addDomain('BioAuthDomain', {
cognitoDomain: {
domainPrefix: 'bio-ai',
},
});

const callbackUrl = 'http://localhost:19006/';
const client = userPool.addClient('BioAuthClient', {
supportedIdentityProviders: [UserPoolClientIdentityProvider.GOOGLE],
oAuth: {
callbackUrls: [callbackUrl],
},
});
const provider = new cdk.aws_cognito.UserPoolIdentityProviderGoogle(
this,
'Google',
{
clientId:
'49839729668-9ptmk3o21cq41ekv1e1shkeqivgjrcjl.apps.googleusercontent.com',
clientSecretValue: googleClientSecret,
userPool: userPool,
scopes: ['email', 'openid'],
}
);
client.node.addDependency(provider);
return { userPool, client };
}
}
Loading

0 comments on commit c1b283d

Please sign in to comment.