⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 117 additions & 38 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"workspaces": [
"packages/hack",
"packages/cdk",
"packages/foo"
"packages/foo",
"packages/process"
],
"devDependencies": {
"@eslint/js": "^9.38.0",
Expand Down
141 changes: 141 additions & 0 deletions packages/cdk/resources/DynamoDb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import {Construct} from "constructs"

import {
AttributeType,
Billing,
TableEncryptionV2,
TableV2
} from "aws-cdk-lib/aws-dynamodb"
import {
AccountRootPrincipal,
AnyPrincipal,
Effect,
ManagedPolicy,
PolicyDocument,
PolicyStatement
} from "aws-cdk-lib/aws-iam"
import {Key} from "aws-cdk-lib/aws-kms"
import {Duration, RemovalPolicy} from "aws-cdk-lib"

export interface DynamodbProps {
readonly stackName: string
}

/**
* Dynamodb tables used for user state information
*/
export class Dynamodb extends Construct {
public readonly processStatus: TableV2
public readonly useProcessStatusKmsKeyPolicy: ManagedPolicy
public readonly processStatusTableWritePolicy: ManagedPolicy
public readonly processStatusTableReadPolicy: ManagedPolicy
//

public constructor(scope: Construct, id: string, props: DynamodbProps) {
super(scope, id)

// KMS key for token mapping table
const processStatusKey = new Key(this, "processStatusKey", {
removalPolicy: RemovalPolicy.DESTROY,
pendingWindow: Duration.days(7),
alias: `${props.stackName}-processStatusKey`,
description: `${props.stackName}-processStatusKey`,
enableKeyRotation: true,
policy: new PolicyDocument({
statements: [
new PolicyStatement({
sid: "Enable IAM User Permissions",
effect: Effect.ALLOW,
actions: [
"kms:*"
],
principals: [
new AccountRootPrincipal
],
resources: ["*"]
})
]
})
})

// Process Status Table
const processStatusTable = new TableV2(this, "processStatusTable", {
partitionKey: {
name: "actionId",
type: AttributeType.STRING
},
tableName: `${props.stackName}-processStatus`,
removalPolicy: RemovalPolicy.DESTROY,
pointInTimeRecoverySpecification: {
pointInTimeRecoveryEnabled: true
},
encryption: TableEncryptionV2.customerManagedKey(processStatusKey),
billing: Billing.onDemand(),
timeToLiveAttribute: "ExpiryTime"
})

// Policy to use token mapping KMS key
const useProcessStatusKmsKey = new ManagedPolicy(this, "UseProcessStatusKMSKeyPolicy", {
statements: [
new PolicyStatement({
actions: [
"kms:DescribeKey",
"kms:GenerateDataKey",
"kms:Encrypt",
"kms:ReEncryptFrom",
"kms:ReEncryptTo",
"kms:Decrypt"
],
resources: [
processStatusKey.keyArn
]
})
]
})

const processStatusReadPolicy = new ManagedPolicy(this, "ProcessStatusReadManagedPolicy", {
statements: [
new PolicyStatement({
actions: [
"dynamodb:GetItem",
"dynamodb:BatchGetItem",
"dynamodb:Scan",
"dynamodb:Query",
"dynamodb:ConditionCheckItem",
"dynamodb:DescribeTable"
],
resources: [
processStatusTable.tableArn,
`${processStatusTable.tableArn}/index/*`
]
})
]
})

const processStatusWritePolicy = new ManagedPolicy(this, "ProcessStatusWriteManagedPolicy", {
statements: [
new PolicyStatement({
actions: [
"dynamodb:PutItem",
"dynamodb:BatchWriteItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"
],
resources: [
processStatusTable.tableArn,
`${processStatusTable.tableArn}/index/*`
]
})
]
})


// Outputs: assign the created resources to the class properties
this.processStatus = processStatusTable
this.useProcessStatusKmsKeyPolicy = useProcessStatusKmsKey
this.processStatusTableWritePolicy = processStatusWritePolicy
this.processStatusTableReadPolicy = processStatusReadPolicy


}
}
13 changes: 13 additions & 0 deletions packages/cdk/resources/Functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface ApiFunctionsProps {
*/
export class ApiFunctions extends Construct {
public readonly fooLambda: TypescriptLambdaFunction
public readonly processLambda: TypescriptLambdaFunction

public constructor(scope: Construct, id: string, props: ApiFunctionsProps) {
super(scope, id)
Expand All @@ -29,7 +30,19 @@ export class ApiFunctions extends Construct {
version: props.version,
commitId: props.commitId
})
const processLambda = new TypescriptLambdaFunction(this, "ProcessLambda", {
functionName: `${props.stackName}-ProcessLambda`,
projectBaseDir: baseDir,
packageBasePath: "packages/process",
entryPoint: "src/handler.ts",
environmentVariables: {},
logRetentionInDays: 30,
logLevel: "DEBUG",
version: props.version,
commitId: props.commitId
})
// Outputs
this.fooLambda = fooLambda
this.processLambda = processLambda
}
}
5 changes: 5 additions & 0 deletions packages/cdk/stacks/HackStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { CloudfrontDistribution } from "../resources/CloudfrontDistribution"
import { getConfigFromEnvVar } from "@nhsdigital/eps-cdk-constructs"
import { ApiFunctions } from "../resources/Functions"
import { addNagSuppressions } from "./nagSuppression"
import { Dynamodb } from "../resources/DynamoDb"

export interface HackStackProps extends StackProps {
readonly serviceName: string
Expand Down Expand Up @@ -176,6 +177,10 @@ export class HackStack extends Stack {
]
})

const dyna = new Dynamodb(this, "Dynamodb", {
stackName: props.stackName
})

// Outputs

// Exports
Expand Down
20 changes: 20 additions & 0 deletions packages/cdk/stacks/nagSuppression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ export const addNagSuppressions = (stack: Stack) => {
}
]
)
safeAddNagSuppression(
stack,
"/HackStack/Dynamodb/ProcessStatusWriteManagedPolicy/Resource",
[
{
id: "AwsSolutions-IAM5",
reason: "this is for hack day stack"
}
]
)
safeAddNagSuppression(
stack,
"/HackStack/Dynamodb/ProcessStatusReadManagedPolicy/Resource",
[
{
id: "AwsSolutions-IAM5",
reason: "this is for hack day stack"
}
]
)

}

32 changes: 32 additions & 0 deletions packages/process/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "process",
"version": "1.0.0",
"description": "Lambda of the procss endpoint",
"main": "status.js",
"author": "NHS Digital",
"license": "MIT",
"scripts": {
"unit": "POWERTOOLS_DEV=true NODE_OPTIONS=--experimental-vm-modules jest --no-cache --coverage",
"lint": "eslint --max-warnings 0 --fix --config ../../eslint.config.mjs .",
"compile": "tsc --build",
"test": "npm run compile && npm run unit",
"check-licenses": "license-checker --failOn GPL --failOn LGPL --start ../.."
},
"dependencies": {
"@aws-lambda-powertools/commons": "^2.30.2",
"@aws-lambda-powertools/logger": "^2.30.2",
"@aws-lambda-powertools/parameters": "^2.30.2",
"@middy/core": "^7.0.2",
"@middy/input-output-logger": "^7.0.2",
"@nhs/fhir-middy-error-handler": "^2.1.71",
"@nhsdigital/eps-spine-client": "^2.1.78",
"axios": "^1.7.9",
"axios-cookiejar-support": "^6.0.4",
"jsdom": "^25.0.1",
"tough-cookie": "^5.1.2"
},
"devDependencies": {
"axios-mock-adapter": "^2.1.0",
"esbuild": "^0.27.2"
}
}
Loading