diff --git a/.github/actions/cached-node-modules/action.yml b/.github/actions/cached-node-modules/action.yml index 008c852792..6d27b04694 100644 --- a/.github/actions/cached-node-modules/action.yml +++ b/.github/actions/cached-node-modules/action.yml @@ -44,5 +44,6 @@ runs: npm run build -w packages/parameters & \ npm run build -w packages/idempotency & \ npm run build -w packages/batch & \ + npm run build -w packages/parser & \ npm run build -w packages/testing shell: bash \ No newline at end of file diff --git a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml index 6b845abe20..a8321ad566 100644 --- a/.github/workflows/reusable-run-linting-check-and-unit-tests.yml +++ b/.github/workflows/reusable-run-linting-check-and-unit-tests.yml @@ -25,9 +25,9 @@ jobs: with: nodeVersion: ${{ matrix.version }} - name: Run linting - run: npm run lint -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch + run: npm run lint -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch -w packages/parser - name: Run unit tests - run: npm t -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch + run: npm t -w packages/commons -w packages/logger -w packages/tracer -w packages/metrics -w packages/parameters -w packages/idempotency -w packages/batch -w packages/parser check-examples: runs-on: ubuntu-latest env: diff --git a/.npmignore b/.npmignore index ec8c75c6f9..54ce5720a8 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,6 @@ src tests -jest.config.js +jest.config.cjs tsconfig.json .vscode .github @@ -13,7 +13,6 @@ coverage tslint.json tsconfig.json MakeFile -jest.config.js .npmignore .eslintignore .huskyrc.js diff --git a/docs/snippets/idempotency/samples/makeIdempotentJmes.json b/docs/snippets/idempotency/samples/makeIdempotentJmes.json index 9f608983da..158b3a874f 100644 --- a/docs/snippets/idempotency/samples/makeIdempotentJmes.json +++ b/docs/snippets/idempotency/samples/makeIdempotentJmes.json @@ -27,4 +27,4 @@ }, "body": "{\"user\":\"xyz\",\"productId\":\"123456789\"}", "isBase64Encoded": false -} \ No newline at end of file +} diff --git a/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeyError.json b/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeyError.json index a905b83e7a..14ca8067ae 100644 --- a/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeyError.json +++ b/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeyError.json @@ -4,4 +4,4 @@ "name": "foo", "productId": 10000 } -} \ No newline at end of file +} diff --git a/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeySuccess.json b/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeySuccess.json index e721b2c24c..ef9c932907 100644 --- a/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeySuccess.json +++ b/docs/snippets/idempotency/samples/workingWIthIdempotencyRequiredKeySuccess.json @@ -4,4 +4,4 @@ "name": "Foo" }, "productId": 10000 -} \ No newline at end of file +} diff --git a/docs/snippets/idempotency/samples/workingWithBatch.json b/docs/snippets/idempotency/samples/workingWithBatch.json index 44bd07a141..73a5029d61 100644 --- a/docs/snippets/idempotency/samples/workingWithBatch.json +++ b/docs/snippets/idempotency/samples/workingWithBatch.json @@ -23,4 +23,4 @@ "awsRegion": "us-east-2" } ] -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index 198ef2f485..2b28ed8c51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "packages/idempotency", "packages/batch", "packages/testing", + "packages/parser", "docs/snippets", "layers", "examples/cdk", @@ -333,6 +334,10 @@ "resolved": "packages/parameters", "link": true }, + "node_modules/@aws-lambda-powertools/parser": { + "resolved": "packages/parser", + "link": true + }, "node_modules/@aws-lambda-powertools/testing-utils": { "resolved": "packages/testing", "link": true @@ -16605,6 +16610,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/batch": { "name": "@aws-lambda-powertools/batch", "version": "1.14.0", @@ -16745,6 +16759,14 @@ } } }, + "packages/parser": { + "name": "@aws-lambda-powertools/parser", + "version": "0.0.0", + "license": "MIT-0", + "peerDependencies": { + "zod": "^3.22.4" + } + }, "packages/testing": { "name": "@aws-lambda-powertools/testing-utils", "version": "1.14.0", diff --git a/packages/parser/jest.config.js b/packages/parser/jest.config.cjs similarity index 77% rename from packages/parser/jest.config.js rename to packages/parser/jest.config.cjs index a4f984ae47..e1dca130b9 100644 --- a/packages/parser/jest.config.js +++ b/packages/parser/jest.config.cjs @@ -5,8 +5,12 @@ module.exports = { }, runner: 'groups', preset: 'ts-jest', + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, transform: { - '^.+\\.ts?$': 'ts-jest', + '^.+\\.ts?$': ['ts-jest', {tsconfig: './tests/tsconfig.json'}], + }, moduleFileExtensions: ['js', 'ts'], collectCoverageFrom: ['**/src/**/*.ts', '!**/node_modules/**'], @@ -14,7 +18,7 @@ module.exports = { roots: ['/src', '/tests'], testPathIgnorePatterns: ['/node_modules/'], testEnvironment: 'node', - coveragePathIgnorePatterns: ['/node_modules/', '/types/'], + coveragePathIgnorePatterns: ['/node_modules/', '/types'], coverageThreshold: { global: { statements: 100, @@ -24,5 +28,4 @@ module.exports = { }, }, coverageReporters: ['json-summary', 'text', 'lcov'], - setupFiles: ['/tests/helpers/populateEnvironmentVariables.ts'], }; diff --git a/packages/parser/package.json b/packages/parser/package.json index c40d714f80..6dd191ca17 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -2,27 +2,45 @@ "name": "@aws-lambda-powertools/parser", "version": "0.0.0", "description": "The parser package for the Powertools for AWS Lambda (TypeScript) library.", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com" + }, + "publishConfig": { + "access": "restricted" + }, "scripts": { "test": "npm run test:unit", "test:unit": "jest --group=unit --detectOpenHandles --coverage --verbose", + "jest": "jest --detectOpenHandles --coverage --verbose", "watch": "jest --watch", - "build": "tsc --build --force", + "build:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json", + "build:esm": "tsc --build tsconfig.esm.json && echo '{ \"type\": \"module\" }' > lib/esm/package.json", + "build": "npm run build:esm & npm run build:cjs", "lint": "eslint --ext .ts,.js --no-error-on-unmatched-pattern .", "lint-fix": "eslint --fix --ext .ts,.js --no-error-on-unmatched-pattern .", - "prebuild": "rimraf ./lib", "prepack": "node ../../.github/scripts/release_patch_package_json.js ." }, - "author": { - "name": "Amazon Web Services", - "url": "https://aws.amazon.com" - }, "lint-staged": { "*.{js,ts}": "npm run lint-fix" }, - "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/batch#readme", + "homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/parser#readme", "license": "MIT-0", - "main": "./lib/index.js", - "types": "./lib/index.d.ts", + "type": "module", + "exports": { + ".": { + "require": { + "types": "./lib/cjs/index.d.ts", + "default": "./lib/cjs/index.js" + }, + "import": { + "types": "./lib/esm/index.d.ts", + "default": "./lib/esm/index.js" + } + } + }, + "main": "./lib/cjs/index.js", + "types": "./lib/cjs/index.d.ts", "files": [ "lib" ], @@ -42,10 +60,8 @@ "serverless", "nodejs" ], - "publishConfig": { - "access": "restricted" - }, - "devDependencies": { - "zod": "^3.22.2" + + "peerDependencies": { + "zod": ">=3.x" } -} +} \ No newline at end of file diff --git a/packages/parser/src/intex.ts b/packages/parser/src/index.ts similarity index 100% rename from packages/parser/src/intex.ts rename to packages/parser/src/index.ts diff --git a/packages/parser/src/schemas/alb.ts b/packages/parser/src/schemas/alb.ts new file mode 100644 index 0000000000..54d5de4fed --- /dev/null +++ b/packages/parser/src/schemas/alb.ts @@ -0,0 +1,22 @@ +import { z } from 'zod'; + +const AlbSchema = z.object({ + httpMethod: z.string(), + path: z.string(), + body: z.string(), + isBase64Encoded: z.boolean(), + headers: z.record(z.string(), z.string()).optional(), + queryStringParameters: z.record(z.string(), z.string()).optional(), + requestContext: z.object({ + elb: z.object({ + targetGroupArn: z.string(), + }), + }), +}); + +const AlbMultiValueHeadersSchema = AlbSchema.extend({ + multiValueHeaders: z.record(z.string(), z.array(z.string())), + multiValueQueryStringParameters: z.record(z.string(), z.array(z.string())), +}); + +export { AlbSchema, AlbMultiValueHeadersSchema }; diff --git a/packages/parser/src/schemas/apigw.ts b/packages/parser/src/schemas/apigw.ts new file mode 100644 index 0000000000..72878de03a --- /dev/null +++ b/packages/parser/src/schemas/apigw.ts @@ -0,0 +1,110 @@ +import { z } from 'zod'; + +const APIGatewayCert = z.object({ + clientCertPem: z.string(), + subjectDN: z.string(), + issuerDN: z.string(), + serialNumber: z.string(), + validity: z.object({ + notBefore: z.string(), + notAfter: z.string(), + }), +}); + +const APIGatewayEventIdentity = z.object({ + accessKey: z.string().nullish(), + accountId: z.string().nullish(), + apiKey: z.string().nullish(), + apiKeyId: z.string().nullish(), + caller: z.string().nullish(), + cognitoAuthenticationProvider: z.string().nullish(), + cognitoAuthenticationType: z.string().nullish(), + cognitoIdentityId: z.string().nullish(), + cognitoIdentityPoolId: z.string().nullish(), + principalOrgId: z.string().nullish(), + sourceIp: z.string().ip().optional(), + user: z.string().nullish(), + userAgent: z.string().nullish(), + userArn: z.string().nullish(), + clientCert: APIGatewayCert.nullish(), +}); + +const APIGatewayEventRequestContext = z + .object({ + accountId: z.string(), + apiId: z.string(), + authorizer: z + .object({ + claims: z.record(z.string(), z.any()).nullish(), + scopes: z.array(z.string()).nullish(), + }) + .nullish(), + stage: z.string(), + protocol: z.string(), + identity: APIGatewayEventIdentity, + requestId: z.string(), + requestTime: z.string(), + requestTimeEpoch: z.number(), + resourceId: z.string().nullish(), + resourcePath: z.string(), + domainName: z.string().nullish(), + domainPrefix: z.string().nullish(), + extendedRequestId: z.string().nullish(), + httpMethod: z.enum([ + 'GET', + 'POST', + 'PUT', + 'PATCH', + 'DELETE', + 'HEAD', + 'OPTIONS', + ]), + path: z.string(), + connectedAt: z.number().nullish(), + connectionId: z.string().nullish(), + eventType: z.enum(['CONNECT', 'MESSAGE', 'DISCONNECT']).nullish(), + messageDirection: z.string().nullish(), + messageId: z.string().nullish(), + routeKey: z.string().nullish(), + operationName: z.string().nullish(), + }) + .refine( + (input) => { + return ( + !input.messageId || (input.messageId && input.eventType === 'MESSAGE') + ); + }, + { + message: 'messageId is available only when `eventType` is MESSAGE', + } + ); + +const APIGatewayProxyEventSchema = z.object({ + version: z.string().optional(), + authorizationToken: z.string().optional(), + identitySource: z.string().optional(), + methodArn: z.string().optional(), + type: z.enum(['TOKEN', 'REQUEST']).optional(), + resource: z.string(), + path: z.string(), + httpMethod: z.enum([ + 'GET', + 'POST', + 'PUT', + 'PATCH', + 'DELETE', + 'HEAD', + 'OPTIONS', + ]), + headers: z.record(z.string()).optional(), + queryStringParameters: z.record(z.string()).optional(), + multiValueHeaders: z.record(z.array(z.string())).optional(), + multiValueQueryStringParameters: z.record(z.array(z.string())).optional(), + requestContext: APIGatewayEventRequestContext, + pathParameters: z.record(z.string()).optional().nullish(), + stageVariables: z.record(z.string()).optional().nullish(), + isBase64Encoded: z.boolean().optional(), + body: z.string().optional(), +}); + +export { APIGatewayProxyEventSchema, APIGatewayCert }; diff --git a/packages/parser/src/schemas/apigwv2.ts b/packages/parser/src/schemas/apigwv2.ts new file mode 100644 index 0000000000..ec5cfb6156 --- /dev/null +++ b/packages/parser/src/schemas/apigwv2.ts @@ -0,0 +1,71 @@ +import { z } from 'zod'; +import { APIGatewayCert } from './apigw.js'; + +const RequestContextV2Authorizer = z.object({ + jwt: z + .object({ + claims: z.record(z.string(), z.any()), + scopes: z.array(z.string()).optional(), + }) + .optional(), + iam: z + .object({ + accessKey: z.string().optional(), + accountId: z.string().optional(), + callerId: z.string().optional(), + principalOrgId: z.string().optional(), + userArn: z.string().optional(), + userId: z.string().optional(), + cognitoIdentity: z.object({ + amr: z.array(z.string()), + identityId: z.string(), + identityPoolId: z.string(), + }), + }) + .optional(), + lambda: z.record(z.string(), z.any()).optional(), +}); + +const RequestContextV2Http = z.object({ + method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']), + path: z.string(), + protocol: z.string(), + sourceIp: z.string().ip(), + userAgent: z.string(), +}); + +const RequestContextV2 = z.object({ + accountId: z.string(), + apiId: z.string(), + authorizer: RequestContextV2Authorizer.optional(), + authentication: z + .object({ + clientCert: APIGatewayCert.optional(), + }) + .optional(), + domainName: z.string(), + domainPrefix: z.string(), + http: RequestContextV2Http, + requestId: z.string(), + routeKey: z.string(), + stage: z.string(), + time: z.string(), + timeEpoch: z.number(), +}); + +const APIGatewayProxyEventV2Schema = z.object({ + version: z.string(), + routeKey: z.string(), + rawPath: z.string(), + rawQueryString: z.string(), + cookies: z.array(z.string()).optional(), + headers: z.record(z.string()), + queryStringParameters: z.record(z.string()).optional(), + pathParameters: z.record(z.string()).optional().nullish(), + stageVariables: z.record(z.string()).optional().nullish(), + requestContext: RequestContextV2, + body: z.string().optional(), + isBase64Encoded: z.boolean(), +}); + +export { APIGatewayProxyEventV2Schema }; diff --git a/packages/parser/src/schemas/cloudformation-custom-resource.ts b/packages/parser/src/schemas/cloudformation-custom-resource.ts new file mode 100644 index 0000000000..13f9e9760d --- /dev/null +++ b/packages/parser/src/schemas/cloudformation-custom-resource.ts @@ -0,0 +1,40 @@ +import { z } from 'zod'; + +const CloudFormationCustomResourceBaseSchema = z.object({ + ServiceToken: z.string(), + ResponseURL: z.string().url(), + StackId: z.string(), + RequestId: z.string(), + LogicalResourceId: z.string(), + ResourceType: z.string(), + ResourceProperties: z.record(z.any()), +}); + +const CloudFormationCustomResourceCreateSchema = + CloudFormationCustomResourceBaseSchema.merge( + z.object({ + RequestType: z.literal('Create'), + }) + ); + +const CloudFormationCustomResourceDeleteSchema = + CloudFormationCustomResourceBaseSchema.merge( + z.object({ + RequestType: z.literal('Delete'), + }) + ); + +const CloudFormationCustomResourceUpdateSchema = + CloudFormationCustomResourceBaseSchema.merge( + z.object({ + RequestType: z.literal('Update'), + OldResourceProperties: z.record(z.any()), + }) + ); + +export { + CloudFormationCustomResourceCreateSchema, + CloudFormationCustomResourceDeleteSchema, + CloudFormationCustomResourceUpdateSchema, + CloudFormationCustomResourceBaseSchema, +}; diff --git a/packages/parser/src/schemas/cloudwatch.ts b/packages/parser/src/schemas/cloudwatch.ts new file mode 100644 index 0000000000..8c9e71f9a0 --- /dev/null +++ b/packages/parser/src/schemas/cloudwatch.ts @@ -0,0 +1,44 @@ +import { z } from 'zod'; +import { gunzipSync } from 'node:zlib'; + +const CloudWatchLogEventSchema = z.object({ + id: z.string(), + timestamp: z.number(), + message: z.string(), +}); + +const CloudWatchLogsDecodeSchema = z.object({ + messageType: z.string(), + owner: z.string(), + logGroup: z.string(), + logStream: z.string(), + subscriptionFilters: z.array(z.string()), + logEvents: z.array(CloudWatchLogEventSchema), +}); + +const decompressRecordToJSON = ( + data: string +): z.infer => { + const uncompressed = gunzipSync(Buffer.from(data, 'base64')).toString('utf8'); + + return CloudWatchLogsDecodeSchema.parse(JSON.parse(uncompressed)); +}; + +const CloudWatchLogsSchema = z.object({ + awslogs: z.object({ + data: z.string().transform((data) => decompressRecordToJSON(data)), + }), +}); + +const extractCloudWatchLogFromEvent = ( + data: string +): z.infer => { + return decompressRecordToJSON(data); +}; + +export { + CloudWatchLogsSchema, + CloudWatchLogsDecodeSchema, + decompressRecordToJSON, + extractCloudWatchLogFromEvent, +}; diff --git a/packages/parser/src/schemas/dynamodb.ts b/packages/parser/src/schemas/dynamodb.ts new file mode 100644 index 0000000000..011ff85f8a --- /dev/null +++ b/packages/parser/src/schemas/dynamodb.ts @@ -0,0 +1,43 @@ +import { z } from 'zod'; + +const DynamoDBStreamChangeRecord = z.object({ + ApproximateCreationDateTime: z.number().optional(), + Keys: z.record(z.string(), z.record(z.string(), z.any())), + NewImage: z.record(z.string(), z.any()).optional(), + OldImage: z.record(z.string(), z.any()).optional(), + SequenceNumber: z.string(), + SizeBytes: z.number(), + StreamViewType: z.enum([ + 'NEW_IMAGE', + 'OLD_IMAGE', + 'NEW_AND_OLD_IMAGES', + 'KEYS_ONLY', + ]), +}); + +const UserIdentity = z.object({ + type: z.enum(['Service']), + principalId: z.literal('dynamodb.amazonaws.com'), +}); + +const DynamoDBStreamRecord = z.object({ + eventID: z.string(), + eventName: z.enum(['INSERT', 'MODIFY', 'REMOVE']), + eventVersion: z.string(), + eventSource: z.literal('aws:dynamodb'), + awsRegion: z.string(), + eventSourceARN: z.string(), + dynamodb: DynamoDBStreamChangeRecord, + userIdentity: UserIdentity.optional(), +}); + +const DynamoDBStreamSchema = z.object({ + Records: z.array(DynamoDBStreamRecord), +}); + +export { + DynamoDBStreamSchema, + DynamoDBStreamRecord, + DynamoDBStreamChangeRecord, + UserIdentity, +}; diff --git a/packages/parser/src/schemas/eventbridge.ts b/packages/parser/src/schemas/eventbridge.ts new file mode 100644 index 0000000000..9c509e5c03 --- /dev/null +++ b/packages/parser/src/schemas/eventbridge.ts @@ -0,0 +1,16 @@ +import { z } from 'zod'; + +const EventBridgeSchema = z.object({ + version: z.string(), + id: z.string(), + source: z.string(), + account: z.string(), + time: z.string().datetime(), + region: z.string(), + resources: z.array(z.string()), + 'detail-type': z.string(), + detail: z.unknown(), + 'replay-name': z.string().optional(), +}); + +export { EventBridgeSchema }; diff --git a/packages/parser/src/schemas/kafka.ts b/packages/parser/src/schemas/kafka.ts new file mode 100644 index 0000000000..880fb404d8 --- /dev/null +++ b/packages/parser/src/schemas/kafka.ts @@ -0,0 +1,44 @@ +import { z } from 'zod'; + +const KafkaRecordSchema = z.object({ + topic: z.string(), + partition: z.number(), + offset: z.number(), + timestamp: z.number(), + timestampType: z.string(), + key: z.string().transform((key) => { + return Buffer.from(key, 'base64').toString(); + }), + value: z.string().transform((value) => { + return Buffer.from(value, 'base64').toString(); + }), + headers: z.array( + z.record( + z.string(), + z.array(z.number()).transform((value) => { + return String.fromCharCode(...value); + }) + ) + ), +}); + +const KafkaBaseEventSchema = z.object({ + bootstrapServers: z + .string() + .transform((bootstrapServers) => { + return bootstrapServers ? bootstrapServers.split(',') : undefined; + }) + .nullish(), + records: z.record(z.string(), z.array(KafkaRecordSchema)), +}); + +const KafkaSelfManagedEventSchema = KafkaBaseEventSchema.extend({ + eventSource: z.literal('aws:SelfManagedKafka'), +}); + +const KafkaMskEventSchema = KafkaBaseEventSchema.extend({ + eventSource: z.literal('aws:kafka'), + eventSourceArn: z.string(), +}); + +export { KafkaSelfManagedEventSchema, KafkaMskEventSchema }; diff --git a/packages/parser/src/schemas/kinesis-firehose.ts b/packages/parser/src/schemas/kinesis-firehose.ts new file mode 100644 index 0000000000..e541cc3f65 --- /dev/null +++ b/packages/parser/src/schemas/kinesis-firehose.ts @@ -0,0 +1,51 @@ +import { z } from 'zod'; +import { SqsRecordSchema } from './sqs.js'; + +const KinesisRecordMetaData = z.object({ + shardId: z.string(), + partitionKey: z.string(), + approximateArrivalTimestamp: z.number().positive(), + sequenceNumber: z.string(), + subsequenceNumber: z.number(), +}); + +const KinesisFireHoseRecordBase = z.object({ + recordId: z.string(), + approximateArrivalTimestamp: z.number().positive(), + kinesisRecordMetaData: KinesisRecordMetaData.optional(), +}); + +const KinesisFireHoseBaseSchema = z.object({ + invocationId: z.string(), + deliveryStreamArn: z.string(), + region: z.string(), + sourceKinesisStreamArn: z.string().optional(), +}); + +const KinesisFirehoseRecord = KinesisFireHoseRecordBase.extend({ + data: z + .string() + .transform((data) => Buffer.from(data, 'base64').toString('utf8')), +}); + +const KinesisFirehoseSqsRecord = KinesisFireHoseRecordBase.extend({ + data: z.string().transform((data) => { + try { + return SqsRecordSchema.parse( + JSON.parse(Buffer.from(data, 'base64').toString('utf8')) + ); + } catch (e) { + return data; + } + }), +}); + +const KinesisFirehoseSchema = KinesisFireHoseBaseSchema.extend({ + records: z.array(KinesisFirehoseRecord), +}); + +const KinesisFirehoseSqsSchema = KinesisFireHoseBaseSchema.extend({ + records: z.array(KinesisFirehoseSqsRecord), +}); + +export { KinesisFirehoseSchema, KinesisFirehoseSqsSchema }; diff --git a/packages/parser/src/schemas/kinesis.ts b/packages/parser/src/schemas/kinesis.ts new file mode 100644 index 0000000000..d598715420 --- /dev/null +++ b/packages/parser/src/schemas/kinesis.ts @@ -0,0 +1,25 @@ +import { z } from 'zod'; + +const KinesisDataStreamRecordPayload = z.object({ + kinesisSchemaVersion: z.string(), + partitionKey: z.string(), + sequenceNumber: z.string(), + approximateArrivalTimestamp: z.number(), + data: z.string(), +}); + +const KinesisDataStreamRecord = z.object({ + eventSource: z.literal('aws:kinesis'), + eventVersion: z.string(), + eventID: z.string(), + eventName: z.literal('aws:kinesis:record'), + invokeIdentityArn: z.string(), + eventSourceARN: z.string(), + kinesis: KinesisDataStreamRecordPayload, +}); + +const KinesisDataStreamSchema = z.object({ + Records: z.array(KinesisDataStreamRecord), +}); + +export { KinesisDataStreamSchema }; diff --git a/packages/parser/src/schemas/lambda.ts b/packages/parser/src/schemas/lambda.ts new file mode 100644 index 0000000000..e8e72be255 --- /dev/null +++ b/packages/parser/src/schemas/lambda.ts @@ -0,0 +1,14 @@ +import { APIGatewayProxyEventV2Schema } from './apigwv2.js'; + +/** + * Lambda Function URL follows the API Gateway HTTP APIs Payload Format Version 2.0. + * + * Keys related to API Gateway features not available in Function URL use a sentinel value (e.g.`routeKey`, `stage`). + * Documentation: + * - https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html + * - https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads + * + */ +const LambdaFunctionUrlSchema = APIGatewayProxyEventV2Schema.extend({}); + +export { LambdaFunctionUrlSchema }; diff --git a/packages/parser/src/schemas/s3.ts b/packages/parser/src/schemas/s3.ts new file mode 100644 index 0000000000..558776ffa5 --- /dev/null +++ b/packages/parser/src/schemas/s3.ts @@ -0,0 +1,164 @@ +import { z } from 'zod'; +import { EventBridgeSchema } from './eventbridge.js'; +import { SqsRecordSchema } from './sqs.js'; + +const S3Identity = z.object({ + principalId: z.string(), +}); + +const S3RequestParameters = z.object({ + sourceIPAddress: z.string().ip(), +}); + +const S3ResponseElements = z.object({ + 'x-amz-request-id': z.string(), + 'x-amz-id-2': z.string(), +}); + +const S3Message = z.object({ + s3SchemaVersion: z.string(), + configurationId: z.string(), + object: z.object({ + key: z.string(), + size: z.number().optional(), + urlDecodedKey: z.string().optional(), + eTag: z.string().optional(), + sequencer: z.string(), + versionId: z.optional(z.string()), + }), + bucket: z.object({ + name: z.string(), + ownerIdentity: S3Identity, + arn: z.string(), + }), +}); + +const S3EventRecordGlacierEventData = z.object({ + restoreEventData: z.object({ + lifecycleRestorationExpiryTime: z.string(), + lifecycleRestoreStorageClass: z.string(), + }), +}); + +const S3RecordSchema = z + .object({ + eventVersion: z.string(), + eventSource: z.literal('aws:s3'), + awsRegion: z.string(), + eventTime: z.string().datetime(), + eventName: z.string(), + userIdentity: S3Identity, + requestParameters: S3RequestParameters, + responseElements: S3ResponseElements, + s3: S3Message, + glacierEventData: z.optional(S3EventRecordGlacierEventData), + }) + .refine((value) => { + return ( + (!value.eventName.includes('ObjectRemoved') && + value.s3.object.size === undefined) || + value.s3.object.eTag === undefined, + { + message: + 'S3 event notification with ObjectRemoved event name must have size or eTag defined', + } + ); + }); + +const S3EventNotificationEventBridgeDetailSchema = z.object({ + version: z.string(), + bucket: z.object({ + name: z.string(), + }), + object: z.object({ + key: z.string(), + size: z.number().nonnegative().optional(), + etag: z.string(), + 'version-id': z.string().optional(), + sequencer: z.string().optional(), + }), + 'request-id': z.string(), + requester: z.string(), + 'source-ip-address': z.string().ip().optional(), + reason: z.string().optional(), + 'deletion-type': z.string().optional(), + 'restore-expiry-time': z.string().optional(), + 'source-storage-class': z.string().optional(), + 'destination-storage-class': z.string().optional(), + 'destination-access-tier': z.string().optional(), +}); + +const S3EventNotificationEventBridgeSchema = EventBridgeSchema.extend({ + detail: S3EventNotificationEventBridgeDetailSchema, +}); + +const S3Schema = z.object({ + Records: z.array(S3RecordSchema), +}); + +const S3SqsEventNotificationRecordSchema = SqsRecordSchema.extend({ + body: z.string(), +}); + +const S3SqsEventNotificationSchema = z.object({ + Records: z.array(S3SqsEventNotificationRecordSchema), +}); + +const S3ObjectContext = z.object({ + inputS3Url: z.string().url(), + outputRoute: z.string(), + outputToken: z.string(), +}); + +const S3ObjectConfiguration = z.object({ + accessPointArn: z.string(), + supportingAccessPointArn: z.string(), + payload: z.union([z.string(), z.object({})]), +}); + +const S3ObjectUserRequest = z.object({ + url: z.string(), + headers: z.record(z.string(), z.string()), +}); + +const S3ObjectSessionContext = z.object({ + sessionIssuer: z.object({ + type: z.string(), + userName: z.string().optional(), + principalId: z.string(), + arn: z.string(), + accountId: z.string(), + }), + attributes: z.object({ + creationDate: z.string(), + mfaAuthenticated: z + .union([z.boolean(), z.literal('true'), z.literal('false')]) + .transform((value) => value === true || value === 'true'), + }), +}); + +const S3ObjectUserIdentity = z.object({ + type: z.string(), + accountId: z.string(), + accessKeyId: z.string(), + userName: z.string().optional(), + principalId: z.string(), + arn: z.string(), + sessionContext: S3ObjectSessionContext.optional(), +}); + +const S3ObjectLambdaEventSchema = z.object({ + xAmzRequestId: z.string(), + getObjectContext: S3ObjectContext, + configuration: S3ObjectConfiguration, + userRequest: S3ObjectUserRequest, + userIdentity: S3ObjectUserIdentity, + protocolVersion: z.string(), +}); + +export { + S3Schema, + S3EventNotificationEventBridgeSchema, + S3SqsEventNotificationSchema, + S3ObjectLambdaEventSchema, +}; diff --git a/packages/parser/src/schemas/ses.ts b/packages/parser/src/schemas/ses.ts new file mode 100644 index 0000000000..254d3de255 --- /dev/null +++ b/packages/parser/src/schemas/ses.ts @@ -0,0 +1,65 @@ +import { z } from 'zod'; + +const SesReceiptVerdict = z.object({ + status: z.enum(['PASS', 'FAIL', 'GRAY', 'PROCESSING_FAILED']), +}); + +const SesReceipt = z.object({ + timestamp: z.string().datetime(), + processingTimeMillis: z.number().int().positive(), + recipients: z.array(z.string()), + spamVerdict: SesReceiptVerdict, + virusVerdict: SesReceiptVerdict, + spfVerdict: SesReceiptVerdict, + dmarcVerdict: SesReceiptVerdict, + dkimVerdict: SesReceiptVerdict, + dmarcPolicy: z.enum(['none', 'quarantine', 'reject']), + action: z.object({ + type: z.enum(['Lambda']), + invocationType: z.literal('Event'), + functionArn: z.string(), + }), +}); + +const SesMail = z.object({ + timestamp: z.string().datetime(), + source: z.string(), + messageId: z.string(), + destination: z.array(z.string()), + headersTruncated: z.boolean(), + headers: z.array( + z.object({ + name: z.string(), + value: z.string(), + }) + ), + commonHeaders: z.object({ + from: z.array(z.string()), + to: z.array(z.string()), + cc: z.array(z.string()).optional(), + bcc: z.array(z.string()).optional(), + sender: z.array(z.string()).optional(), + 'reply-to': z.array(z.string()).optional(), + returnPath: z.string(), + messageId: z.string(), + date: z.string(), + subject: z.string(), + }), +}); + +const SesMessage = z.object({ + mail: SesMail, + receipt: SesReceipt, +}); + +const SesRecordSchema = z.object({ + eventSource: z.literal('aws:ses'), + eventVersion: z.string(), + ses: SesMessage, +}); + +const SesSchema = z.object({ + Records: z.array(SesRecordSchema), +}); + +export { SesSchema, SesRecordSchema }; diff --git a/packages/parser/src/schemas/sns.ts b/packages/parser/src/schemas/sns.ts new file mode 100644 index 0000000000..f8d8d8bbc4 --- /dev/null +++ b/packages/parser/src/schemas/sns.ts @@ -0,0 +1,33 @@ +import { z } from 'zod'; + +const SnsMsgAttribute = z.object({ + Type: z.string(), + Value: z.string(), +}); + +const SnsNotificationSchema = z.object({ + Subject: z.string().optional(), + TopicArn: z.string(), + UnsubscribeUrl: z.string().url(), + Type: z.literal('Notification'), + MessageAttributes: z.record(z.string(), SnsMsgAttribute).optional(), + Message: z.string(), + MessageId: z.string(), + Signature: z.string().optional(), + SignatureVersion: z.string().optional(), + SigningCertUrl: z.string().url().optional(), + Timestamp: z.string().datetime(), +}); + +const SnsRecordSchema = z.object({ + EventSource: z.literal('aws:sns'), + EventVersion: z.string(), + EventSubscriptionArn: z.string(), + Sns: SnsNotificationSchema, +}); + +const SnsSchema = z.object({ + Records: z.array(SnsRecordSchema), +}); + +export { SnsSchema, SnsRecordSchema, SnsNotificationSchema, SnsMsgAttribute }; diff --git a/packages/parser/src/schemas/sqs.ts b/packages/parser/src/schemas/sqs.ts new file mode 100644 index 0000000000..09aed635ea --- /dev/null +++ b/packages/parser/src/schemas/sqs.ts @@ -0,0 +1,44 @@ +import { z } from 'zod'; + +const SqsMsgAttributeSchema = z.object({ + stringValue: z.string().optional(), + binaryValue: z.string().optional(), + stringListValues: z.array(z.string()).optional(), + binaryListValues: z.array(z.string()).optional(), + dataType: z.string(), +}); + +const SqsAttributesSchema = z.object({ + ApproximateReceiveCount: z.string(), + ApproximateFirstReceiveTimestamp: z.string(), + MessageDeduplicationId: z.string().optional(), + MessageGroupId: z.string().optional(), + SenderId: z.string(), + SentTimestamp: z.string(), + SequenceNumber: z.string().optional(), + AWSTraceHeader: z.string().optional(), +}); + +const SqsRecordSchema = z.object({ + messageId: z.string(), + receiptHandle: z.string(), + body: z.string(), + attributes: SqsAttributesSchema, + messageAttributes: z.record(z.string(), SqsMsgAttributeSchema), + md5OfBody: z.string(), + md5OfMessageAttributes: z.string().optional().nullable(), + eventSource: z.literal('aws:sqs'), + eventSourceARN: z.string(), + awsRegion: z.string(), +}); + +const SqsSchema = z.object({ + Records: z.array(SqsRecordSchema), +}); + +export { + SqsSchema, + SqsRecordSchema, + SqsAttributesSchema, + SqsMsgAttributeSchema, +}; diff --git a/packages/parser/src/schemas/vpc-lattice.ts b/packages/parser/src/schemas/vpc-lattice.ts new file mode 100644 index 0000000000..f8f266fa20 --- /dev/null +++ b/packages/parser/src/schemas/vpc-lattice.ts @@ -0,0 +1,12 @@ +import { z } from 'zod'; + +const VpcLatticeSchema = z.object({ + method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']), + raw_path: z.string(), + body: z.string(), + is_base64_encoded: z.boolean(), + headers: z.record(z.string(), z.string()), + query_string_parameters: z.record(z.string(), z.string()), +}); + +export { VpcLatticeSchema }; diff --git a/packages/parser/src/schemas/vpc-latticev2.ts b/packages/parser/src/schemas/vpc-latticev2.ts new file mode 100644 index 0000000000..1ef3fd671f --- /dev/null +++ b/packages/parser/src/schemas/vpc-latticev2.ts @@ -0,0 +1,36 @@ +import { z } from 'zod'; + +const VpcLatticeV2RequestContextIdentity = z.object({ + sourceVpcArn: z.string().optional(), + type: z.string().optional(), + principal: z.string().optional(), + principalOrgId: z.string().optional(), + sessionName: z.string().optional(), + X509SubjectCn: z.string().optional(), + X509IssuerOu: z.string().optional(), + x509SanDns: z.string().optional(), + x509SanUri: z.string().optional(), + X509SanNameCn: z.string().optional(), +}); + +const VpcLatticeV2RequestContext = z.object({ + serviceNetworkArn: z.string(), + serviceArn: z.string(), + targetGroupArn: z.string(), + region: z.string(), + timeEpoch: z.string(), + identity: VpcLatticeV2RequestContextIdentity, +}); + +const VpcLatticeV2Schema = z.object({ + version: z.string(), + path: z.string(), + method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']), + headers: z.record(z.string(), z.string()), + queryStringParameters: z.record(z.string(), z.string()).optional(), + body: z.string().optional(), + isBase64Encoded: z.boolean().optional(), + requestContext: VpcLatticeV2RequestContext, +}); + +export { VpcLatticeV2Schema }; diff --git a/packages/parser/tests/events/activeMQEvent.json b/packages/parser/tests/events/activeMQEvent.json new file mode 100644 index 0000000000..57417cfd22 --- /dev/null +++ b/packages/parser/tests/events/activeMQEvent.json @@ -0,0 +1,55 @@ +{ + "eventSource": "aws:amq", + "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8", + "messages": [ + { + "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/text-message", + "data": "QUJDOkFBQUE=", + "connectionId": "myJMSCoID", + "redelivered": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959, + "properties": { + "testKey": "testValue" + } + }, + { + "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/text-message", + "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ==", + "connectionId": "myJMSCoID2", + "redelivered": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959, + "properties": { + "testKey": "testValue" + } + + }, + { + "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1", + "messageType": "jms/bytes-message", + "data": "3DTOOW7crj51prgVLQaGQ82S48k=", + "connectionId": "myJMSCoID1", + "persistent": false, + "destination": { + "physicalname": "testQueue" + }, + "timestamp": 1598827811958, + "brokerInTime": 1598827811958, + "brokerOutTime": 1598827811959, + "properties": { + "testKey": "testValue" + } + } + ] +} diff --git a/packages/parser/tests/events/albEvent.json b/packages/parser/tests/events/albEvent.json new file mode 100644 index 0000000000..9328cb39e1 --- /dev/null +++ b/packages/parser/tests/events/albEvent.json @@ -0,0 +1,28 @@ +{ + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a" + } + }, + "httpMethod": "GET", + "path": "/lambda", + "queryStringParameters": { + "query": "1234ABCD" + }, + "headers": { + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "accept-encoding": "gzip", + "accept-language": "en-US,en;q=0.9", + "connection": "keep-alive", + "host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com", + "upgrade-insecure-requests": "1", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36", + "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476", + "x-forwarded-for": "72.12.164.125", + "x-forwarded-port": "80", + "x-forwarded-proto": "http", + "x-imforwards": "20" + }, + "body": "Test", + "isBase64Encoded": false +} diff --git a/packages/parser/tests/events/albEventPathTrailingSlash.json b/packages/parser/tests/events/albEventPathTrailingSlash.json new file mode 100644 index 0000000000..c517a3f6b0 --- /dev/null +++ b/packages/parser/tests/events/albEventPathTrailingSlash.json @@ -0,0 +1,28 @@ +{ + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a" + } + }, + "httpMethod": "GET", + "path": "/lambda/", + "queryStringParameters": { + "query": "1234ABCD" + }, + "headers": { + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "accept-encoding": "gzip", + "accept-language": "en-US,en;q=0.9", + "connection": "keep-alive", + "host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com", + "upgrade-insecure-requests": "1", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36", + "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476", + "x-forwarded-for": "72.12.164.125", + "x-forwarded-port": "80", + "x-forwarded-proto": "http", + "x-imforwards": "20" + }, + "body": "Test", + "isBase64Encoded": false + } \ No newline at end of file diff --git a/packages/parser/tests/events/albMultiValueHeadersEvent.json b/packages/parser/tests/events/albMultiValueHeadersEvent.json new file mode 100644 index 0000000000..6b34709605 --- /dev/null +++ b/packages/parser/tests/events/albMultiValueHeadersEvent.json @@ -0,0 +1,35 @@ +{ + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:eu-central-1:1234567890:targetgroup/alb-c-Targe-11GDXTPQ7663S/804a67588bfdc10f" + } + }, + "httpMethod": "GET", + "path": "/todos", + "multiValueQueryStringParameters": {}, + "multiValueHeaders": { + "accept": [ + "*/*" + ], + "host": [ + "alb-c-LoadB-14POFKYCLBNSF-1815800096.eu-central-1.elb.amazonaws.com" + ], + "user-agent": [ + "curl/7.79.1" + ], + "x-amzn-trace-id": [ + "Root=1-62fa9327-21cdd4da4c6db451490a5fb7" + ], + "x-forwarded-for": [ + "123.123.123.123" + ], + "x-forwarded-port": [ + "80" + ], + "x-forwarded-proto": [ + "http" + ] + }, + "body": "", + "isBase64Encoded": false +} diff --git a/packages/parser/tests/events/apiGatewayAuthorizerRequestEvent.json b/packages/parser/tests/events/apiGatewayAuthorizerRequestEvent.json new file mode 100644 index 0000000000..6a80fff823 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayAuthorizerRequestEvent.json @@ -0,0 +1,68 @@ +{ + "version": "1.0", + "type": "REQUEST", + "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", + "identitySource": "user1,123", + "authorizationToken": "user1,123", + "resource": "/request", + "path": "/request", + "httpMethod": "GET", + "headers": { + "X-AMZ-Date": "20170718T062915Z", + "Accept": "*/*", + "HeaderAuth1": "headerValue1", + "CloudFront-Viewer-Country": "US", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Is-Mobile-Viewer": "false", + "User-Agent": "..." + }, + "queryStringParameters": { + "QueryString1": "queryValue1" + }, + "pathParameters": {}, + "stageVariables": { + "StageVar1": "stageValue1" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "abcdef123", + "domainName": "3npb9j1tlk.execute-api.us-west-1.amazonaws.com", + "domainPrefix": "3npb9j1tlk", + "extendedRequestId": "EXqgWgXxSK4EJug=", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "apiKey": "...", + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "PostmanRuntime/7.28.3", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/request", + "protocol": "HTTP/1.1", + "requestId": "EXqgWgXxSK4EJug=", + "requestTime": "20/Aug/2021:14:36:50 +0000", + "requestTimeEpoch": 1629470210043, + "resourceId": "ANY /request", + "resourcePath": "/request", + "stage": "test" + } +} diff --git a/packages/parser/tests/events/apiGatewayAuthorizerTokenEvent.json b/packages/parser/tests/events/apiGatewayAuthorizerTokenEvent.json new file mode 100644 index 0000000000..f30f360f6d --- /dev/null +++ b/packages/parser/tests/events/apiGatewayAuthorizerTokenEvent.json @@ -0,0 +1,5 @@ +{ + "type": "TOKEN", + "authorizationToken": "allow", + "methodArn": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/" +} diff --git a/packages/parser/tests/events/apiGatewayAuthorizerV2Event.json b/packages/parser/tests/events/apiGatewayAuthorizerV2Event.json new file mode 100644 index 0000000000..f0528080c9 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayAuthorizerV2Event.json @@ -0,0 +1,52 @@ +{ + "version": "2.0", + "type": "REQUEST", + "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request", + "identitySource": ["user1", "123"], + "routeKey": "GET /merchants", + "rawPath": "/merchants", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": ["cookie1", "cookie2"], + "headers": { + "x-amzn-trace-id": "Root=1-611cc4a7-0746ebee281cfd967db97b64", + "Header1": "value1", + "Header2": "value2", + "Authorization": "value" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "POST", + "path": "/merchants", + "protocol": "HTTP/1.1", + "sourceIp": "IP", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "GET /merchants", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "pathParameters": { "parameter1": "value1" }, + "stageVariables": { "stageVariable1": "value1", "stageVariable2": "value2" } +} diff --git a/packages/parser/tests/events/apiGatewayProxyEvent.json b/packages/parser/tests/events/apiGatewayProxyEvent.json new file mode 100644 index 0000000000..4d2fb62399 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyEvent.json @@ -0,0 +1,81 @@ +{ + "version": "1.0", + "resource": "/my/path", + "path": "/my/path", + "httpMethod": "GET", + "headers": { + "Header1": "value1", + "Header2": "value2", + "Origin": "https://aws.amazon.com" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "authorizer": { + "claims": null, + "scopes": null + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/my/path", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/my/path", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "Hello from Lambda!", + "isBase64Encoded": false +} \ No newline at end of file diff --git a/packages/parser/tests/events/apiGatewayProxyEventAnotherPath.json b/packages/parser/tests/events/apiGatewayProxyEventAnotherPath.json new file mode 100644 index 0000000000..660118a2f9 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyEventAnotherPath.json @@ -0,0 +1,80 @@ +{ + "version": "1.0", + "resource": "/my/anotherPath", + "path": "/my/anotherPath", + "httpMethod": "GET", + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "authorizer": { + "claims": null, + "scopes": null + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/my/anotherPath", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/my/anotherPath", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "Hello from Lambda!", + "isBase64Encoded": true +} \ No newline at end of file diff --git a/packages/parser/tests/events/apiGatewayProxyEventPathTrailingSlash.json b/packages/parser/tests/events/apiGatewayProxyEventPathTrailingSlash.json new file mode 100644 index 0000000000..ced73da8c9 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyEventPathTrailingSlash.json @@ -0,0 +1,80 @@ +{ + "version": "1.0", + "resource": "/my/path", + "path": "/my/path/", + "httpMethod": "GET", + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "authorizer": { + "claims": null, + "scopes": null + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/my/path", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/my/path", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "Hello from Lambda!", + "isBase64Encoded": true + } \ No newline at end of file diff --git a/packages/parser/tests/events/apiGatewayProxyEventPrincipalId.json b/packages/parser/tests/events/apiGatewayProxyEventPrincipalId.json new file mode 100644 index 0000000000..f18a2a44bb --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyEventPrincipalId.json @@ -0,0 +1,13 @@ +{ + "resource": "/trip", + "path": "/trip", + "httpMethod": "POST", + "requestContext": { + "requestId": "34972478-2843-4ced-a657-253108738274", + "authorizer": { + "user_id": "fake_username", + "principalId": "fake", + "integrationLatency": 451 + } + } +} diff --git a/packages/parser/tests/events/apiGatewayProxyEvent_noVersionAuth.json b/packages/parser/tests/events/apiGatewayProxyEvent_noVersionAuth.json new file mode 100644 index 0000000000..3a4af1ae9a --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyEvent_noVersionAuth.json @@ -0,0 +1,75 @@ +{ + "resource": "/my/path", + "path": "/my/path", + "httpMethod": "GET", + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/my/path", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/my/path", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "Hello from Lambda!", + "isBase64Encoded": true +} diff --git a/packages/parser/tests/events/apiGatewayProxyOtherEvent.json b/packages/parser/tests/events/apiGatewayProxyOtherEvent.json new file mode 100644 index 0000000000..7d5f0ef753 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyOtherEvent.json @@ -0,0 +1,81 @@ +{ + "version": "1.0", + "resource": "/other/path", + "path": "/other/path", + "httpMethod": "GET", + "headers": { + "Header1": "value1", + "Header2": "value2", + "Origin": "https://aws.amazon.com" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "authorizer": { + "claims": null, + "scopes": null + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/other/path", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/other/path", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "Hello from Lambda!", + "isBase64Encoded": false +} diff --git a/packages/parser/tests/events/apiGatewayProxyV2Event.json b/packages/parser/tests/events/apiGatewayProxyV2Event.json new file mode 100644 index 0000000000..ac287d560a --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2Event.json @@ -0,0 +1,69 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "authorizer": { + "jwt": { + "claims": { + "claim1": "value1", + "claim2": "value2" + }, + "scopes": [ + "scope1", + "scope2" + ] + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "body": "{\"message\": \"hello world\", \"username\": \"tom\"}", + "pathParameters": { + "parameter1": "value1" + }, + "isBase64Encoded": false, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + } +} diff --git a/packages/parser/tests/events/apiGatewayProxyV2EventPathTrailingSlash.json b/packages/parser/tests/events/apiGatewayProxyV2EventPathTrailingSlash.json new file mode 100644 index 0000000000..6a745937ca --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2EventPathTrailingSlash.json @@ -0,0 +1,69 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path/", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "authorizer": { + "jwt": { + "claims": { + "claim1": "value1", + "claim2": "value2" + }, + "scopes": [ + "scope1", + "scope2" + ] + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "body": "{\"message\": \"hello world\", \"username\": \"tom\"}", + "pathParameters": { + "parameter1": "value1" + }, + "isBase64Encoded": false, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + } + } \ No newline at end of file diff --git a/packages/parser/tests/events/apiGatewayProxyV2Event_GET.json b/packages/parser/tests/events/apiGatewayProxyV2Event_GET.json new file mode 100644 index 0000000000..34b9b04628 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2Event_GET.json @@ -0,0 +1,68 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "authorizer": { + "jwt": { + "claims": { + "claim1": "value1", + "claim2": "value2" + }, + "scopes": [ + "scope1", + "scope2" + ] + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "GET", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "pathParameters": { + "parameter1": "value1" + }, + "isBase64Encoded": false, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + } +} diff --git a/packages/parser/tests/events/apiGatewayProxyV2IamEvent.json b/packages/parser/tests/events/apiGatewayProxyV2IamEvent.json new file mode 100644 index 0000000000..99f10ef989 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2IamEvent.json @@ -0,0 +1,62 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "pathParameters": { + "proxy": "hello/world" + }, + "requestContext": { + "routeKey": "$default", + "accountId": "123456789012", + "stage": "$default", + "requestId": "id", + "authorizer": { + "iam": { + "accessKey": "ARIA2ZJZYVUEREEIHAKY", + "accountId": "1234567890", + "callerId": "AROA7ZJZYVRE7C3DUXHH6:CognitoIdentityCredentials", + "cognitoIdentity": { + "amr": [ + "foo" + ], + "identityId": "us-east-1:3f291106-8703-466b-8f2b-3ecee1ca56ce", + "identityPoolId": "us-east-1:4f291106-8703-466b-8f2b-3ecee1ca56ce" + }, + "principalOrgId": "AwsOrgId", + "userArn": "arn:aws:iam::1234567890:user/Admin", + "userId": "AROA2ZJZYVRE7Y3TUXHH6" + } + }, + "apiId": "api-id", + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "time": "12/Mar/2020:19:03:58+0000", + "timeEpoch": 1583348638390, + "http": { + "method": "GET", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + } + }, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + }, + "body": "{\r\n\t\"a\": 1\r\n}", + "isBase64Encoded": false +} \ No newline at end of file diff --git a/packages/parser/tests/events/apiGatewayProxyV2LambdaAuthorizerEvent.json b/packages/parser/tests/events/apiGatewayProxyV2LambdaAuthorizerEvent.json new file mode 100644 index 0000000000..e7e6aeb2ca --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2LambdaAuthorizerEvent.json @@ -0,0 +1,50 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "pathParameters": { + "proxy": "hello/world" + }, + "requestContext": { + "routeKey": "$default", + "accountId": "123456789012", + "stage": "$default", + "requestId": "id", + "authorizer": { + "lambda": { + "key": "value" + } + }, + "apiId": "api-id", + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "time": "12/Mar/2020:19:03:58+0000", + "timeEpoch": 1583348638390, + "http": { + "method": "GET", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + } + }, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + }, + "body": "{\r\n\t\"a\": 1\r\n}", + "isBase64Encoded": false +} \ No newline at end of file diff --git a/packages/parser/tests/events/apiGatewayProxyV2OtherGetEvent.json b/packages/parser/tests/events/apiGatewayProxyV2OtherGetEvent.json new file mode 100644 index 0000000000..c5499c46b4 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2OtherGetEvent.json @@ -0,0 +1,68 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/other/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "authorizer": { + "jwt": { + "claims": { + "claim1": "value1", + "claim2": "value2" + }, + "scopes": [ + "scope1", + "scope2" + ] + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "GET", + "path": "/other/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "pathParameters": { + "parameter1": "value1" + }, + "isBase64Encoded": false, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + } +} diff --git a/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareInvalidEvent.json b/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareInvalidEvent.json new file mode 100644 index 0000000000..5b663ec40a --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareInvalidEvent.json @@ -0,0 +1,69 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "authorizer": { + "jwt": { + "claims": { + "claim1": "value1", + "claim2": "value2" + }, + "scopes": [ + "scope1", + "scope2" + ] + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "body": "{\"username\": \"lessa\"}", + "pathParameters": { + "parameter1": "value1" + }, + "isBase64Encoded": false, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + } +} diff --git a/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareValidEvent.json b/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareValidEvent.json new file mode 100644 index 0000000000..f59a6ef318 --- /dev/null +++ b/packages/parser/tests/events/apiGatewayProxyV2SchemaMiddlewareValidEvent.json @@ -0,0 +1,69 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "api-id", + "authentication": { + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "authorizer": { + "jwt": { + "claims": { + "claim1": "value1", + "claim2": "value2" + }, + "scopes": [ + "scope1", + "scope2" + ] + } + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "192.168.0.1", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "body": "{\"message\": \"hello world\", \"username\": \"lessa\"}", + "pathParameters": { + "parameter1": "value1" + }, + "isBase64Encoded": false, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + } +} diff --git a/packages/parser/tests/events/apiGatewaySchemaMiddlewareInvalidEvent.json b/packages/parser/tests/events/apiGatewaySchemaMiddlewareInvalidEvent.json new file mode 100644 index 0000000000..f601583a76 --- /dev/null +++ b/packages/parser/tests/events/apiGatewaySchemaMiddlewareInvalidEvent.json @@ -0,0 +1,81 @@ +{ + "version": "1.0", + "resource": "/my/path", + "path": "/my/path", + "httpMethod": "POST", + "headers": { + "Header1": "value1", + "Header2": "value2", + "Origin": "https://aws.amazon.com" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "authorizer": { + "claims": null, + "scopes": null + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/my/path", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/my/path", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "{\"username\": \"lessa\"}", + "isBase64Encoded": false +} diff --git a/packages/parser/tests/events/apiGatewaySchemaMiddlewareValidEvent.json b/packages/parser/tests/events/apiGatewaySchemaMiddlewareValidEvent.json new file mode 100644 index 0000000000..7437eba9e0 --- /dev/null +++ b/packages/parser/tests/events/apiGatewaySchemaMiddlewareValidEvent.json @@ -0,0 +1,81 @@ +{ + "version": "1.0", + "resource": "/my/path", + "path": "/my/path", + "httpMethod": "POST", + "headers": { + "Header1": "value1", + "Header2": "value2", + "Origin": "https://aws.amazon.com" + }, + "multiValueHeaders": { + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, + "queryStringParameters": { + "parameter1": "value1", + "parameter2": "value" + }, + "multiValueQueryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "id", + "authorizer": { + "claims": null, + "scopes": null + }, + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "extendedRequestId": "request-id", + "httpMethod": "GET", + "identity": { + "accessKey": null, + "accountId": null, + "caller": null, + "cognitoAuthenticationProvider": null, + "cognitoAuthenticationType": null, + "cognitoIdentityId": null, + "cognitoIdentityPoolId": null, + "principalOrgId": null, + "sourceIp": "192.168.0.1", + "user": null, + "userAgent": "user-agent", + "userArn": null, + "clientCert": { + "clientCertPem": "CERT_CONTENT", + "subjectDN": "www.example.com", + "issuerDN": "Example issuer", + "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", + "validity": { + "notBefore": "May 28 12:30:02 2019 GMT", + "notAfter": "Aug 5 09:36:04 2021 GMT" + } + } + }, + "path": "/my/path", + "protocol": "HTTP/1.1", + "requestId": "id=", + "requestTime": "04/Mar/2020:19:15:17 +0000", + "requestTimeEpoch": 1583349317135, + "resourceId": null, + "resourcePath": "/my/path", + "stage": "$default" + }, + "pathParameters": null, + "stageVariables": null, + "body": "{\"message\": \"hello world\", \"username\": \"lessa\"}", + "isBase64Encoded": false +} diff --git a/packages/parser/tests/events/appSyncAuthorizerEvent.json b/packages/parser/tests/events/appSyncAuthorizerEvent.json new file mode 100644 index 0000000000..a8264569bf --- /dev/null +++ b/packages/parser/tests/events/appSyncAuthorizerEvent.json @@ -0,0 +1,13 @@ +{ + "authorizationToken": "BE9DC5E3-D410-4733-AF76-70178092E681", + "requestContext": { + "apiId": "giy7kumfmvcqvbedntjwjvagii", + "accountId": "254688921111", + "requestId": "b80ed838-14c6-4500-b4c3-b694c7bef086", + "queryString": "mutation MyNewTask($desc: String!) {\n createTask(description: $desc, owner: \"ccc\", taskStatus: \"cc\", title: \"ccc\") {\n id\n }\n}\n", + "operationName": "MyNewTask", + "variables": { + "desc": "Foo" + } + } +} diff --git a/packages/parser/tests/events/appSyncAuthorizerResponse.json b/packages/parser/tests/events/appSyncAuthorizerResponse.json new file mode 100644 index 0000000000..7dd8234d2e --- /dev/null +++ b/packages/parser/tests/events/appSyncAuthorizerResponse.json @@ -0,0 +1,9 @@ +{ + "isAuthorized": true, + "resolverContext": { + "name": "Foo Man", + "balance": 100 + }, + "deniedFields": ["Mutation.createEvent"], + "ttlOverride": 15 +} diff --git a/packages/parser/tests/events/appSyncDirectResolver.json b/packages/parser/tests/events/appSyncDirectResolver.json new file mode 100644 index 0000000000..08c3d00b20 --- /dev/null +++ b/packages/parser/tests/events/appSyncDirectResolver.json @@ -0,0 +1,74 @@ +{ + "arguments": { + "id": "my identifier" + }, + "identity": { + "claims": { + "sub": "192879fc-a240-4bf1-ab5a-d6a00f3063f9", + "email_verified": true, + "iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-xxxxxxxxxxx", + "phone_number_verified": false, + "cognito:username": "jdoe", + "aud": "7471s60os7h0uu77i1tk27sp9n", + "event_id": "bc334ed8-a938-4474-b644-9547e304e606", + "token_use": "id", + "auth_time": 1599154213, + "phone_number": "+19999999999", + "exp": 1599157813, + "iat": 1599154213, + "email": "jdoe@email.com" + }, + "defaultAuthStrategy": "ALLOW", + "groups": null, + "issuer": "https://cognito-idp.us-west-2.amazonaws.com/us-west-xxxxxxxxxxx", + "sourceIp": [ + "1.1.1.1" + ], + "sub": "192879fc-a240-4bf1-ab5a-d6a00f3063f9", + "username": "jdoe" + }, + "source": null, + "request": { + "headers": { + "x-forwarded-for": "1.1.1.1, 2.2.2.2", + "cloudfront-viewer-country": "US", + "cloudfront-is-tablet-viewer": "false", + "via": "2.0 xxxxxxxxxxxxxxxx.cloudfront.net (CloudFront)", + "cloudfront-forwarded-proto": "https", + "origin": "https://us-west-1.console.aws.amazon.com", + "content-length": "217", + "accept-language": "en-US,en;q=0.9", + "host": "xxxxxxxxxxxxxxxx.appsync-api.us-west-1.amazonaws.com", + "x-forwarded-proto": "https", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36", + "accept": "*/*", + "cloudfront-is-mobile-viewer": "false", + "cloudfront-is-smarttv-viewer": "false", + "accept-encoding": "gzip, deflate, br", + "referer": "https://us-west-1.console.aws.amazon.com/appsync/home?region=us-west-1", + "content-type": "application/json", + "sec-fetch-mode": "cors", + "x-amz-cf-id": "3aykhqlUwQeANU-HGY7E_guV5EkNeMMtwyOgiA==", + "x-amzn-trace-id": "Root=1-5f512f51-fac632066c5e848ae714", + "authorization": "eyJraWQiOiJScWFCSlJqYVJlM0hrSnBTUFpIcVRXazNOW...", + "sec-fetch-dest": "empty", + "x-amz-user-agent": "AWS-Console-AppSync/", + "cloudfront-is-desktop-viewer": "true", + "sec-fetch-site": "cross-site", + "x-forwarded-port": "443" + } + }, + "prev": null, + "info": { + "selectionSetList": [ + "id", + "field1", + "field2" + ], + "selectionSetGraphQL": "{\n id\n field1\n field2\n}", + "parentTypeName": "Mutation", + "fieldName": "createSomething", + "variables": {} + }, + "stash": {} +} diff --git a/packages/parser/tests/events/appSyncResolverEvent.json b/packages/parser/tests/events/appSyncResolverEvent.json new file mode 100644 index 0000000000..84ac71951c --- /dev/null +++ b/packages/parser/tests/events/appSyncResolverEvent.json @@ -0,0 +1,71 @@ +{ + "typeName": "Merchant", + "fieldName": "locations", + "arguments": { + "page": 2, + "size": 1, + "name": "value" + }, + "identity": { + "claims": { + "sub": "07920713-4526-4642-9c88-2953512de441", + "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_POOL_ID", + "aud": "58rc9bf5kkti90ctmvioppukm9", + "event_id": "7f4c9383-abf6-48b7-b821-91643968b755", + "token_use": "id", + "auth_time": 1615366261, + "name": "Michael Brewer", + "exp": 1615369861, + "iat": 1615366261 + }, + "defaultAuthStrategy": "ALLOW", + "groups": null, + "issuer": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_POOL_ID", + "sourceIp": [ + "11.215.2.22" + ], + "sub": "07920713-4526-4642-9c88-2953512de441", + "username": "mike" + }, + "source": { + "name": "Value", + "nested": { + "name": "value", + "list": [] + } + }, + "request": { + "headers": { + "x-forwarded-for": "11.215.2.22, 64.44.173.11", + "cloudfront-viewer-country": "US", + "cloudfront-is-tablet-viewer": "false", + "via": "2.0 SOMETHING.cloudfront.net (CloudFront)", + "cloudfront-forwarded-proto": "https", + "origin": "https://console.aws.amazon.com", + "content-length": "156", + "accept-language": "en-US,en;q=0.9", + "host": "SOMETHING.appsync-api.us-east-1.amazonaws.com", + "x-forwarded-proto": "https", + "sec-gpc": "1", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) etc.", + "accept": "*/*", + "cloudfront-is-mobile-viewer": "false", + "cloudfront-is-smarttv-viewer": "false", + "accept-encoding": "gzip, deflate, br", + "referer": "https://console.aws.amazon.com/", + "content-type": "application/json", + "sec-fetch-mode": "cors", + "x-amz-cf-id": "Fo5VIuvP6V6anIEt62WzFDCK45mzM4yEdpt5BYxOl9OFqafd-WR0cA==", + "x-amzn-trace-id": "Root=1-60488877-0b0c4e6727ab2a1c545babd0", + "authorization": "AUTH-HEADER", + "sec-fetch-dest": "empty", + "x-amz-user-agent": "AWS-Console-AppSync/", + "cloudfront-is-desktop-viewer": "true", + "sec-fetch-site": "cross-site", + "x-forwarded-port": "443" + } + }, + "prev": { + "result": {} + } +} diff --git a/packages/parser/tests/events/awsConfigRuleConfigurationChanged.json b/packages/parser/tests/events/awsConfigRuleConfigurationChanged.json new file mode 100644 index 0000000000..cbf7abf67a --- /dev/null +++ b/packages/parser/tests/events/awsConfigRuleConfigurationChanged.json @@ -0,0 +1,13 @@ +{ + "version":"1.0", + "invokingEvent":"{\"configurationItemDiff\":{\"changedProperties\":{\"Configuration.InstanceType\":{\"previousValue\":\"t2.micro\",\"updatedValue\":\"t2.medium\",\"changeType\":\"UPDATE\"},\"Configuration.State.Name\":{\"previousValue\":\"running\",\"updatedValue\":\"stopped\",\"changeType\":\"UPDATE\"},\"Configuration.StateTransitionReason\":{\"previousValue\":\"\",\"updatedValue\":\"User initiated (2023-04-27 15:01:07 GMT)\",\"changeType\":\"UPDATE\"},\"Configuration.StateReason\":{\"previousValue\":null,\"updatedValue\":{\"code\":\"Client.UserInitiatedShutdown\",\"message\":\"Client.UserInitiatedShutdown: User initiated shutdown\"},\"changeType\":\"CREATE\"},\"Configuration.CpuOptions.CoreCount\":{\"previousValue\":1,\"updatedValue\":2,\"changeType\":\"UPDATE\"}},\"changeType\":\"UPDATE\"},\"configurationItem\":{\"relatedEvents\":[],\"relationships\":[{\"resourceId\":\"eipalloc-0ebb4367662263cc1\",\"resourceName\":null,\"resourceType\":\"AWS::EC2::EIP\",\"name\":\"Is attached to ElasticIp\"},{\"resourceId\":\"eni-034dd31c4b17ada8c\",\"resourceName\":null,\"resourceType\":\"AWS::EC2::NetworkInterface\",\"name\":\"Contains NetworkInterface\"},{\"resourceId\":\"eni-09a604c0ec356b06f\",\"resourceName\":null,\"resourceType\":\"AWS::EC2::NetworkInterface\",\"name\":\"Contains NetworkInterface\"},{\"resourceId\":\"sg-0fb295a327d9b4835\",\"resourceName\":null,\"resourceType\":\"AWS::EC2::SecurityGroup\",\"name\":\"Is associated with SecurityGroup\"},{\"resourceId\":\"subnet-cad1f2f4\",\"resourceName\":null,\"resourceType\":\"AWS::EC2::Subnet\",\"name\":\"Is contained in Subnet\"},{\"resourceId\":\"vol-0a288b5eb9fea4b30\",\"resourceName\":null,\"resourceType\":\"AWS::EC2::Volume\",\"name\":\"Is attached to Volume\"},{\"resourceId\":\"vpc-2d96be57\",\"resourceName\":null,\"resourceType\":\"AWS::EC2::VPC\",\"name\":\"Is contained in Vpc\"}],\"configuration\":{\"amiLaunchIndex\":0,\"imageId\":\"ami-09d95fab7fff3776c\",\"instanceId\":\"i-042dd005362091826\",\"instanceType\":\"t2.medium\",\"kernelId\":null,\"keyName\":\"mihaec2\",\"launchTime\":\"2023-04-27T14:57:16.000Z\",\"monitoring\":{\"state\":\"disabled\"},\"placement\":{\"availabilityZone\":\"us-east-1e\",\"affinity\":null,\"groupName\":\"\",\"partitionNumber\":null,\"hostId\":null,\"tenancy\":\"default\",\"spreadDomain\":null,\"hostResourceGroupArn\":null},\"platform\":null,\"privateDnsName\":\"ip-172-31-78-41.ec2.internal\",\"privateIpAddress\":\"172.31.78.41\",\"productCodes\":[],\"publicDnsName\":\"ec2-3-232-229-57.compute-1.amazonaws.com\",\"publicIpAddress\":\"3.232.229.57\",\"ramdiskId\":null,\"state\":{\"code\":80,\"name\":\"stopped\"},\"stateTransitionReason\":\"User initiated (2023-04-27 15:01:07 GMT)\",\"subnetId\":\"subnet-cad1f2f4\",\"vpcId\":\"vpc-2d96be57\",\"architecture\":\"x86_64\",\"blockDeviceMappings\":[{\"deviceName\":\"/dev/xvda\",\"ebs\":{\"attachTime\":\"2020-05-30T15:21:58.000Z\",\"deleteOnTermination\":true,\"status\":\"attached\",\"volumeId\":\"vol-0a288b5eb9fea4b30\"}}],\"clientToken\":\"\",\"ebsOptimized\":false,\"enaSupport\":true,\"hypervisor\":\"xen\",\"iamInstanceProfile\":{\"arn\":\"arn:aws:iam::0123456789012:instance-profile/AmazonSSMRoleForInstancesQuickSetup\",\"id\":\"AIPAS5S4WFUBL72S3QXW5\"},\"instanceLifecycle\":null,\"elasticGpuAssociations\":[],\"elasticInferenceAcceleratorAssociations\":[],\"networkInterfaces\":[{\"association\":{\"carrierIp\":null,\"ipOwnerId\":\"0123456789012\",\"publicDnsName\":\"ec2-3-232-229-57.compute-1.amazonaws.com\",\"publicIp\":\"3.232.229.57\"},\"attachment\":{\"attachTime\":\"2020-05-30T15:21:57.000Z\",\"attachmentId\":\"eni-attach-0a7e75dc9c1c291a0\",\"deleteOnTermination\":true,\"deviceIndex\":0,\"status\":\"attached\",\"networkCardIndex\":0},\"description\":\"\",\"groups\":[{\"groupName\":\"minhaec2\",\"groupId\":\"sg-0fb295a327d9b4835\"}],\"ipv6Addresses\":[],\"macAddress\":\"06:cf:00:c2:17:db\",\"networkInterfaceId\":\"eni-034dd31c4b17ada8c\",\"ownerId\":\"0123456789012\",\"privateDnsName\":\"ip-172-31-78-41.ec2.internal\",\"privateIpAddress\":\"172.31.78.41\",\"privateIpAddresses\":[{\"association\":{\"carrierIp\":null,\"ipOwnerId\":\"0123456789012\",\"publicDnsName\":\"ec2-3-232-229-57.compute-1.amazonaws.com\",\"publicIp\":\"3.232.229.57\"},\"primary\":true,\"privateDnsName\":\"ip-172-31-78-41.ec2.internal\",\"privateIpAddress\":\"172.31.78.41\"}],\"sourceDestCheck\":true,\"status\":\"in-use\",\"subnetId\":\"subnet-cad1f2f4\",\"vpcId\":\"vpc-2d96be57\",\"interfaceType\":\"interface\"},{\"association\":null,\"attachment\":{\"attachTime\":\"2020-11-26T23:46:04.000Z\",\"attachmentId\":\"eni-attach-0e6d150ebbd19966e\",\"deleteOnTermination\":false,\"deviceIndex\":1,\"status\":\"attached\",\"networkCardIndex\":0},\"description\":\"MINHAEC2AAAAAA\",\"groups\":[{\"groupName\":\"minhaec2\",\"groupId\":\"sg-0fb295a327d9b4835\"},{\"groupName\":\"default\",\"groupId\":\"sg-88105fa0\"}],\"ipv6Addresses\":[],\"macAddress\":\"06:0a:62:00:64:5f\",\"networkInterfaceId\":\"eni-09a604c0ec356b06f\",\"ownerId\":\"0123456789012\",\"privateDnsName\":\"ip-172-31-70-9.ec2.internal\",\"privateIpAddress\":\"172.31.70.9\",\"privateIpAddresses\":[{\"association\":null,\"primary\":true,\"privateDnsName\":\"ip-172-31-70-9.ec2.internal\",\"privateIpAddress\":\"172.31.70.9\"}],\"sourceDestCheck\":true,\"status\":\"in-use\",\"subnetId\":\"subnet-cad1f2f4\",\"vpcId\":\"vpc-2d96be57\",\"interfaceType\":\"interface\"}],\"outpostArn\":null,\"rootDeviceName\":\"/dev/xvda\",\"rootDeviceType\":\"ebs\",\"securityGroups\":[{\"groupName\":\"minhaec2\",\"groupId\":\"sg-0fb295a327d9b4835\"}],\"sourceDestCheck\":true,\"spotInstanceRequestId\":null,\"sriovNetSupport\":null,\"stateReason\":{\"code\":\"Client.UserInitiatedShutdown\",\"message\":\"Client.UserInitiatedShutdown: User initiated shutdown\"},\"tags\":[{\"key\":\"projeto\",\"value\":\"meetup\"},{\"key\":\"Name\",\"value\":\"Minha\"},{\"key\":\"CentroCusto\",\"value\":\"TI\"},{\"key\":\"Setor\",\"value\":\"Desenvolvimento\"}],\"virtualizationType\":\"hvm\",\"cpuOptions\":{\"coreCount\":2,\"threadsPerCore\":1},\"capacityReservationId\":null,\"capacityReservationSpecification\":{\"capacityReservationPreference\":\"open\",\"capacityReservationTarget\":null},\"hibernationOptions\":{\"configured\":false},\"licenses\":[],\"metadataOptions\":{\"state\":\"applied\",\"httpTokens\":\"optional\",\"httpPutResponseHopLimit\":1,\"httpEndpoint\":\"enabled\"},\"enclaveOptions\":{\"enabled\":false},\"bootMode\":null},\"supplementaryConfiguration\":{},\"tags\":{\"projeto\":\"meetup\",\"Setor\":\"Desenvolvimento\",\"CentroCusto\":\"TI\",\"Name\":\"Minha\"},\"configurationItemVersion\":\"1.3\",\"configurationItemCaptureTime\":\"2023-04-27T15:03:11.636Z\",\"configurationStateId\":1682607791636,\"awsAccountId\":\"0123456789012\",\"configurationItemStatus\":\"OK\",\"resourceType\":\"AWS::EC2::Instance\",\"resourceId\":\"i-042dd005362091826\",\"resourceName\":null,\"ARN\":\"arn:aws:ec2:us-east-1:0123456789012:instance/i-042dd005362091826\",\"awsRegion\":\"us-east-1\",\"availabilityZone\":\"us-east-1e\",\"configurationStateMd5Hash\":\"\",\"resourceCreationTime\":\"2023-04-27T14:57:16.000Z\"},\"notificationCreationTime\":\"2023-04-27T15:03:13.332Z\",\"messageType\":\"ConfigurationItemChangeNotification\",\"recordVersion\":\"1.3\"}", + "ruleParameters":"{\"desiredInstanceType\": \"t2.micro\"}", + "resultToken":"eyJlbmNyeXB0ZWREYXRhIjpbLTQxLDEsLTU3LC0zMCwtMTIxLDUzLDUyLDQ1LC01NywtOCw3MywtODEsLTExNiwtMTAyLC01MiwxMTIsLTQ3LDU4LDY1LC0xMjcsMTAyLDUsLTY5LDQ0LC0xNSwxMTQsNDEsLTksMTExLC0zMCw2NSwtNzUsLTM1LDU0LDEwNSwtODksODYsNDAsLTEwNSw5OCw2NSwtMTE5LC02OSwyNCw2NiwtMjAsODAsLTExMiwtNzgsLTgwLDQzLC01NywzMCwtMjUsODIsLTEwLDMsLTQsLTg1LC01MywtMzcsLTkwLC04OCwtOTgsLTk4LC00MSwxOSwxMTYsNjIsLTIzLC0xMjEsLTEwOCw1NywtNTgsLTUyLDI5LDEwMSwxMjIsLTU2LC03MSwtODEsLTQ3LDc3LC0yMiwtMTI0LC0zLC04NiwtMTIyLC00MCwtODksLTEwMSw1NywtMTI3LC0zNywtMzcsLTMxLC05OCwtMzEsMTEsLTEyNSwwLDEwOCwtMzIsNjQsNjIsLTIyLDAsNDcsLTEwNiwtMTAwLDEwNCwxNCw1OCwxMjIsLTEwLC01MCwtOTAsLTgwLC01MCwtNSw2NSwwLC0yNSw4NSw4Miw3LDkzLDEyMiwtODIsLTExNiwtNzksLTQ0LDcyLC03MywtNjksMTQsLTU2LDk0LDkwLDExNCwtMjksLTExOSwtNzEsODgsMTA3LDEwNywxMTAsLTcsMTI3LC0xMjUsLTU3LC0xMjYsLTEyMCw2OSwtMTI3LC03NiwtMTE5LDcxLDEsLTY4LDEwNywxMTMsLTU2LDg3LC0xMDIsLTE2LDEwOCwtMTA3LC00MywtOTQsLTEwNiwzLDkwLDE0LDcyLC0xMiwtMTE2LC03Myw4MCwtMTIyLDQ0LC0xMDQsMTIsNzQsNTcsLTEwLC0xMDUsLTExMiwtMzYsMjgsLTQ1LDk3LDExLC00OSwtMTEsNjEsMzYsLTE3LC03NCw1MCw0LC0yNiwxMDQsLTI4LC0xMjUsMjQsNzAsLTg1LC00Niw5MiwtMTAzLC00MSwtMTA2LDY5LDEyMiwyMSwtMjUsODAsOTksLTkzLC01NiwtMjUsLTQ3LC0xMjMsLTU5LC0xMjQsLTUyLC0xNiwxMjcsLTM4LC0xNiwxMDEsMTE5LDEwNywyNywxMCwtNDYsLTg3LC0xMiwtMzksMTQsNDUsMiw3MCwxMDcsMTA0LC00LC02OSwtMTIsNTksLTEyNiwtOTEsMTI3LDU0LDEwNiwtMTI2LC0xMTYsLTEwMiw3Miw4MSw1MCw3NSwtNTEsMTA4LDQxLC0zLC02LC00NSwxMDMsLTg2LDM3LC00NiwtMzIsLTExMSwxMjQsMTExLDg3LDU0LC03NiwxMjIsLTUsLTM2LC04OCw5LC0xMTMsMTE2LC01OSw4Myw3NywyOCwxMiwtNjUsLTExMywtNzksLTEyOCw4MiwtMTE4LC04MywtMTI0LDMxLDk5LC05MCwtOTksMTYsLTEyMywyMSwtMTE0LC05OCwtMTE2LC0xMTksMiwtNzMsNDYsODIsLTEzLDU0LDcxLC00MiwyNSw3NCw3MywtODYsOTQsNDYsOTksOTMsLTgyLDU1LDY1LC05OCw0OSwtNjAsMTEyLDEwMSwyMiw2OSwtMTYsNzcsLTk0LC01OSwtNDYsMTE1LDMwLC00Myw5Myw4OCwtMjgsMzgsNiw4NCwzMSwtMTAxLDMyLC0yMiwtNjMsLTk1LDExNCwtNzUsMTE0LDM2LC04NCw0MCwtNDQsLTEzLDU5LDcyLC0xLC0xMDMsMzEsMTA1LDY5LDY5LDc3LC02NCwtNTYsMTE4LDEzLC0xMTQsODAsOTksLTUzLDI1LDQyLDk0LDczLC04MCwyNSwzOCwyNCwtMTcsNjYsLTExOCwtMjMsMTE5LDkwLDEyMSwxMTgsLTUxLDUxLC0xMiwtNzYsLTUxLDksLTIxLDExNCwtMzcsLTY0LC0yLC0xMjYsLTk1LDYzLDczLC00MSwtMzQsLTkwLC0yMiw1OSwtNzksMzAsLTQsLTEsLTUsMTIsMzksLTk5LC0xMDUsLTEwNCwtNjEsNjUsLTc0LDE5LC0xMywtNjAsLTI4LC04LDQsLTgsMTIxLC0xMTgsMTIyLC02NSwtMjEsMjMsMTcsLTg0LDQwLC05MiwxNCwtMTI2LC02MCwtNzksLTUzLDM3LC04Myw2NSwxMDQsLTM2LC02MCwtMTEwLC0zMywtMTE3LDYsMTA3LDEsLTMsOTMsNzgsLTk1LC0xMjIsNTMsMTA4LC00OSwtNDksMjQsLTY1LDgzLDEyNSwtNzcsLTE5LC04MSwzNCwtNjcsLTQzLC03MCwtMjYsMTgsMTA0LDY1LDQsLTEyNiw0NCwtMTE5LDUyLC00NiwyMiw2NywxMTMsMTE4LC0zMywzNCwtOTYsMTIxLDE5LC0yLC0zNSwwLC04MiwxNyw2NiwtMjcsNjksLTM2LC0xNCw1NiwtOTcsLTE2LDEyMywyOCwtOTUsLTMyLC02MywtNjksNzAsNjQsLTMzLC0xMDAsNDMsLTExMywxMDUsMTAwLDEwOCwtNjAsNDAsLTIsLTk2LC0xMjQsMzcsLTQ1LC0xMjQsLTY4LC02OSwtMTIzLDE3LC02LDg2LC01OSwtOTQsMTEwLDczLDU3LC0xMTYsMTA3LC00MSwtOTQsLTExOCwtMTI2LDEwLC04MCwtNzAsMTAyLDg4LC0xMjYsODcsLTI3LC0xMDEsLTk0LC0zNSwtMTA2LC02LC03MiwtODYsNTAsMTE2LC0yOCw5MCwxMywtMTIwLDYsMjcsOTIsNTYsLTkwLDM5LDQ5LC0xMywtODYsLTI1LC04NiwxMTMsLTEzLDQxLC0xMTksOTQsLTk0LC0xMDMsLTgzLC02MCwxMjcsLTE1LC0zOSwxMTksLTk1LDI3LDQ0LDExNiwxMDksNywtMTAyLC0xNyw0OCwtODIsLTMxLC04LC02OSwzNSw5NCw1NCwtNTUsMSwtMTE5LDU3LC0xMDgsLTMsLTkxLC0xMjIsLTUzLC04OCw0LC05NywtMzUsMTI2LDExOSw1OSwtMSw4NSw3MywtNTgsLTEyMCwtNjQsMTE5LC0xMTIsOTIsMTksOSwtNjYsLTkyLDEwOCwtMTEsLTQyLDExMSwtMTA0LC0xMjAsMjcsLTEwMywtNjksMTksMTExLDEyLDIzLDEwNyw1NCw0MSwtMjYsNjAsLTMxLC01XSwibWF0ZXJpYWxTZXRTZXJpYWxOdW1iZXIiOjEsIml2UGFyYW1ldGVyU3BlYyI6eyJpdiI6Wy05NSwzMiwxMDgsOTEsMzUsLTgyLC0zNywyNCwtNDQsLTExNSwtODIsLTEyOCwtMTIyLDMsNTMsLTI0XX19", + "eventLeftScope":false, + "executionRoleArn":"arn:aws:iam::0123456789012:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig", + "configRuleArn":"arn:aws:config:us-east-1:0123456789012:config-rule/config-rule-i9y8j9", + "configRuleName":"MyRule", + "configRuleId":"config-rule-i9y8j9", + "accountId":"0123456789012", + "evaluationMode":"DETECTIVE" + } diff --git a/packages/parser/tests/events/awsConfigRuleOversizedConfiguration.json b/packages/parser/tests/events/awsConfigRuleOversizedConfiguration.json new file mode 100644 index 0000000000..5eaef4e001 --- /dev/null +++ b/packages/parser/tests/events/awsConfigRuleOversizedConfiguration.json @@ -0,0 +1,12 @@ +{ + "invokingEvent": "{\"configurationItemSummary\": {\"changeType\": \"UPDATE\",\"configurationItemVersion\": \"1.2\",\"configurationItemCaptureTime\":\"2016-10-06T16:46:16.261Z\",\"configurationStateId\": 0,\"awsAccountId\":\"123456789012\",\"configurationItemStatus\": \"OK\",\"resourceType\": \"AWS::EC2::Instance\",\"resourceId\":\"i-00000000\",\"resourceName\":null,\"ARN\":\"arn:aws:ec2:us-west-2:123456789012:instance/i-00000000\",\"awsRegion\": \"us-west-2\",\"availabilityZone\":\"us-west-2a\",\"configurationStateMd5Hash\":\"8f1ee69b287895a0f8bc5753eca68e96\",\"resourceCreationTime\":\"2016-10-06T16:46:10.489Z\"},\"messageType\":\"OversizedConfigurationItemChangeNotification\", \"notificationCreationTime\": \"2016-10-06T16:46:16.261Z\", \"recordVersion\": \"1.0\"}", + "ruleParameters": "{\"myParameterKey\":\"myParameterValue\"}", + "resultToken": "myResultToken", + "eventLeftScope": false, + "executionRoleArn": "arn:aws:iam::123456789012:role/config-role", + "configRuleArn": "arn:aws:config:us-east-2:123456789012:config-rule/config-rule-ec2-managed-instance-inventory", + "configRuleName": "change-triggered-config-rule", + "configRuleId": "config-rule-0123456", + "accountId": "123456789012", + "version": "1.0" +} diff --git a/packages/parser/tests/events/awsConfigRuleScheduled.json b/packages/parser/tests/events/awsConfigRuleScheduled.json new file mode 100644 index 0000000000..02ce2a0700 --- /dev/null +++ b/packages/parser/tests/events/awsConfigRuleScheduled.json @@ -0,0 +1,13 @@ +{ + "version":"1.0", + "invokingEvent":"{\"awsAccountId\":\"0123456789012\",\"notificationCreationTime\":\"2023-04-27T13:26:17.741Z\",\"messageType\":\"ScheduledNotification\",\"recordVersion\":\"1.0\"}", + "ruleParameters":"{\"test\":\"x\"}", + "resultToken":"eyJlbmNyeXB0ZWREYXRhIjpbLTQyLDEyNiw1MiwtMzcsLTI5LDExNCwxMjYsLTk3LDcxLDIyLC0xMTAsMTEyLC0zMSwtOTMsLTQ5LC0xMDEsODIsMyw1NCw0OSwzLC02OSwtNzEsLTcyLDYyLDgxLC03MiwtODEsNTAsMzUsLTUwLC03NSwtMTE4LC0xMTgsNzcsMTIsLTEsMTQsMTIwLC03MCwxMTAsLTMsNTAsLTYwLDEwNSwtNTcsNDUsMTAyLC0xMDksLTYxLC0xMDEsLTYxLDQsNDcsLTg0LC0yNSwxMTIsNTQsLTcxLC0xMDksNDUsMTksMTIzLC0yNiwxMiwtOTYsLTczLDU0LC0xMDksOTIsNDgsLTU5LC04MywtMzIsODIsLTM2LC05MCwxOSw5OCw3Nyw3OCw0MCw4MCw3OCwtMTA1LDg3LC0xMTMsLTExNiwtNzIsMzAsLTY4LC00MCwtODksMTA5LC0xMDgsLTEyOCwyMiw3Miw3NywtMjEsNzYsODksOTQsLTU5LDgxLC0xMjEsLTEwNywtNjcsNjMsLTcsODIsLTg5LC00NiwtMzQsLTkyLDEyMiwtOTAsMTcsLTEyMywyMCwtODUsLTU5LC03MCw4MSwyNyw2Miw3NCwtODAsODAsMzcsNDAsMTE2LDkxLC0yNCw1MSwtNDEsLTc5LDI4LDEyMCw1MywtMTIyLC04MywxMjYsLTc4LDI1LC05OCwtMzYsMTMsMzIsODYsLTI1LDQ4LDMsLTEwMiwtMTYsMjQsLTMsODUsNDQsLTI4LDE0LDIyLDI3LC0xMjIsMTE4LDEwMSw3Myw1LDE4LDU4LC02NCwyMywtODYsLTExNCwyNCwwLDEwMCwyLDExNywtNjIsLTExOSwtMTI4LDE4LDY1LDkwLDE0LC0xMDIsMjEsODUsMTAwLDExNyw1NSwyOSwxMjcsNTQsNzcsNzIsNzQsMzIsNzgsMywtMTExLDExOCwtNzAsLTg2LDEyNywtNzQsNjAsMjIsNDgsMzcsODcsMTMsMCwtMTA1LDUsLTEyMiwtNzEsLTEwMCwxMDQsLTEyNiwtMTYsNzksLTMwLDEyMCw3NywtNzYsLTQxLC0xMDksMiw5NywtMTAxLC0xLDE1LDEyMywxMTksMTA4LDkxLC0yMCwtMTI1LC05NiwyLC05MiwtMTUsLTY3LC03NiwxMjEsMTA0LDEwNSw2NCwtNjIsMTAyLDgsNCwxMjEsLTQ1LC04MCwtODEsLTgsMTE4LDQ0LC04MiwtNDEsLTg0LDczLC0zNiwxMTcsODAsLTY5LC03MywxNCwtMTgsNzIsMzEsLTUsLTExMSwtMTI3LC00MywzNCwtOCw1NywxMDMsLTQyLDE4LC0zMywxMTcsLTI2LC0xMjQsLTEyNCwxNSw4OCwyMywxNiwtNTcsNTQsLTYsLTEwMiwxMTYsLTk5LC00NSwxMDAsLTM1LDg3LDM3LDYsOTgsMiwxMTIsNjAsLTMzLDE3LDI2LDk5LC0xMDUsNDgsLTEwNCwtMTE5LDc4LDYsLTU4LDk1LDksNDEsLTE2LDk2LDQxLC0yMiw5Niw3MiwxMTYsLTk1LC0xMDUsLTM2LC0xMjMsLTU1LDkxLC00NiwtNywtOTIsMzksNDUsODQsMTYsLTEyNCwtMTIyLC02OCwxLC0yOCwxMjIsLTYwLDgyLDEwMywtNTQsLTkyLDI3LC05OSwtMTI4LDY1LDcsLTcyLC0xMjcsNjIsLTIyLDIsLTExLDE4LC04OSwtMTA2LC03NCw3MSw4NiwtMTE2LC0yNSwtMTE1LC05Niw1NywtMzQsMjIsLTEyNCwtMTI1LC00LC00MSw0MiwtNTcsLTEwMyw0NSw3OCwxNCwtMTA2LDExMSw5OCwtOTQsLTcxLDUsNzUsMTksLTEyNCwtMzAsMzQsLTUwLDc1LC04NCwtNTAsLTU2LDUxLC0xNSwtMzYsNjEsLTk0LC03OSwtNDUsMTI2LC03NywtMTA1LC0yLC05MywtNiw4LC0zLDYsLTQyLDQ2LDEyNSw1LC05OCwxMyw2NywtMTAsLTEzLC05NCwtNzgsLTEyNywxMjEsLTI2LC04LC0xMDEsLTkxLDEyMSwtNDAsLTEyNCwtNjQsODQsLTcyLDYzLDE5LC04NF0sIm1hdGVyaWFsU2V0U2VyaWFsTnVtYmVyIjoxLCJpdlBhcmFtZXRlclNwZWMiOnsiaXYiOlszLC0xMCwtODUsMTE0LC05MCwxMTUsNzcsNTUsNTQsMTUsMzgsODQsLTExNiwxNCwtNDAsMjhdfX0=", + "eventLeftScope":false, + "executionRoleArn":"arn:aws:iam::0123456789012:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig", + "configRuleArn":"arn:aws:config:us-east-1:0123456789012:config-rule/config-rule-pdmyw1", + "configRuleName":"rule-ec2-test", + "configRuleId":"config-rule-pdmyw1", + "accountId":"0123456789012", + "evaluationMode":"DETECTIVE" + } diff --git a/packages/parser/tests/events/bedrockAgentEvent.json b/packages/parser/tests/events/bedrockAgentEvent.json new file mode 100644 index 0000000000..b7ad75b3c4 --- /dev/null +++ b/packages/parser/tests/events/bedrockAgentEvent.json @@ -0,0 +1,16 @@ +{ + "actionGroup": "ClaimManagementActionGroup", + "messageVersion": "1.0", + "sessionId": "12345678912345", + "sessionAttributes": {}, + "promptSessionAttributes": {}, + "inputText": "I want to claim my insurance", + "agent": { + "alias": "TSTALIASID", + "name": "test", + "version": "DRAFT", + "id": "8ZXY0W8P1H" + }, + "httpMethod": "GET", + "apiPath": "/claims" +} diff --git a/packages/parser/tests/events/bedrockAgentPostEvent.json b/packages/parser/tests/events/bedrockAgentPostEvent.json new file mode 100644 index 0000000000..f223bfcd51 --- /dev/null +++ b/packages/parser/tests/events/bedrockAgentPostEvent.json @@ -0,0 +1,35 @@ +{ + "actionGroup": "ClaimManagementActionGroup", + "messageVersion": "1.0", + "sessionId": "12345678912345", + "sessionAttributes": {}, + "promptSessionAttributes": {}, + "inputText": "Send reminders to all pending documents", + "agent": { + "alias": "TSTALIASID", + "name": "test", + "version": "DRAFT", + "id": "8ZXY0W8P1H" + }, + "httpMethod": "POST", + "apiPath": "/send-reminders", + "requestBody": { + "content": { + "application/json": { + "properties": [ + { + "name": "claimId", + "type": "string", + "value": "20" + }, + { + "name": "pendingDocuments", + "type": "string", + "value": "social number and vat" + } + ] + } + } + }, + "parameters": [] +} diff --git a/packages/parser/tests/events/cloudFormationCustomResourceCreateEvent.json b/packages/parser/tests/events/cloudFormationCustomResourceCreateEvent.json new file mode 100644 index 0000000000..5c32d8c7aa --- /dev/null +++ b/packages/parser/tests/events/cloudFormationCustomResourceCreateEvent.json @@ -0,0 +1,13 @@ +{ + "RequestType": "Create", + "ServiceToken": "arn:aws:lambda:us-east-1:xxx:function:xxxx-CrbuiltinfunctionidProvi-2vKAalSppmKe", + "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/7F%7Cb1f50fdfc25f3b", + "StackId": "arn:aws:cloudformation:us-east-1:xxxx:stack/xxxx/271845b0-f2e8-11ed-90ac-0eeb25b8ae21", + "RequestId": "xxxxx-d2a0-4dfb-ab1f-xxxxxx", + "LogicalResourceId": "xxxxxxxxx", + "ResourceType": "Custom::MyType", + "ResourceProperties": { + "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx", + "MyProps": "ss" + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/cloudFormationCustomResourceDeleteEvent.json b/packages/parser/tests/events/cloudFormationCustomResourceDeleteEvent.json new file mode 100644 index 0000000000..f26738133d --- /dev/null +++ b/packages/parser/tests/events/cloudFormationCustomResourceDeleteEvent.json @@ -0,0 +1,13 @@ +{ + "RequestType": "Delete", + "ServiceToken": "arn:aws:lambda:us-east-1:xxx:function:xxxx-CrbuiltinfunctionidProvi-2vKAalSppmKe", + "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/7F%7Cb1f50fdfc25f3b", + "StackId": "arn:aws:cloudformation:us-east-1:xxxx:stack/xxxx/271845b0-f2e8-11ed-90ac-0eeb25b8ae21", + "RequestId": "xxxxx-d2a0-4dfb-ab1f-xxxxxx", + "LogicalResourceId": "xxxxxxxxx", + "ResourceType": "Custom::MyType", + "ResourceProperties": { + "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx", + "MyProps": "ss" + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/cloudFormationCustomResourceUpdateEvent.json b/packages/parser/tests/events/cloudFormationCustomResourceUpdateEvent.json new file mode 100644 index 0000000000..5225746345 --- /dev/null +++ b/packages/parser/tests/events/cloudFormationCustomResourceUpdateEvent.json @@ -0,0 +1,17 @@ +{ + "RequestType": "Update", + "ServiceToken": "arn:aws:lambda:us-east-1:xxx:function:xxxx-CrbuiltinfunctionidProvi-2vKAalSppmKe", + "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/7F%7Cb1f50fdfc25f3b", + "StackId": "arn:aws:cloudformation:us-east-1:xxxx:stack/xxxx/271845b0-f2e8-11ed-90ac-0eeb25b8ae21", + "RequestId": "xxxxx-d2a0-4dfb-ab1f-xxxxxx", + "LogicalResourceId": "xxxxxxxxx", + "ResourceType": "Custom::MyType", + "ResourceProperties": { + "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx", + "MyProps": "new" + }, + "OldResourceProperties": { + "ServiceToken": "arn:aws:lambda:us-east-1:xxxxx:function:xxxxx-xxxx-xxx", + "MyProps": "old" + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/cloudWatchDashboardEvent.json b/packages/parser/tests/events/cloudWatchDashboardEvent.json new file mode 100644 index 0000000000..fd2d3be62d --- /dev/null +++ b/packages/parser/tests/events/cloudWatchDashboardEvent.json @@ -0,0 +1,38 @@ +{ + "original": "param-to-widget", + "widgetContext": { + "dashboardName": "Name-of-current-dashboard", + "widgetId": "widget-16", + "domain": "https://us-east-1.console.aws.amazon.com", + "accountId": "123456789123", + "locale": "en", + "timezone": { + "label": "UTC", + "offsetISO": "+00:00", + "offsetInMinutes": 0 + }, + "period": 300, + "isAutoPeriod": true, + "timeRange": { + "mode": "relative", + "start": 1627236199729, + "end": 1627322599729, + "relativeStart": 86400012, + "zoom": { + "start": 1627276030434, + "end": 1627282956521 + } + }, + "theme": "light", + "linkCharts": true, + "title": "Tweets for Amazon website problem", + "forms": { + "all": {} + }, + "params": { + "original": "param-to-widget" + }, + "width": 588, + "height": 369 + } +} diff --git a/packages/parser/tests/events/cloudWatchLogEvent.json b/packages/parser/tests/events/cloudWatchLogEvent.json new file mode 100644 index 0000000000..aa184c1d01 --- /dev/null +++ b/packages/parser/tests/events/cloudWatchLogEvent.json @@ -0,0 +1,5 @@ +{ + "awslogs": { + "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA==" + } +} diff --git a/packages/parser/tests/events/codePipelineEvent.json b/packages/parser/tests/events/codePipelineEvent.json new file mode 100644 index 0000000000..d7abe51346 --- /dev/null +++ b/packages/parser/tests/events/codePipelineEvent.json @@ -0,0 +1,34 @@ +{ + "CodePipeline.job": { + "id": "11111111-abcd-1111-abcd-111111abcdef", + "accountId": "111111111111", + "data": { + "actionConfiguration": { + "configuration": { + "FunctionName": "MyLambdaFunctionForAWSCodePipeline", + "UserParameters": "some-input-such-as-a-URL" + } + }, + "inputArtifacts": [ + { + "name": "ArtifactName", + "revision": null, + "location": { + "type": "S3", + "s3Location": { + "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", + "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip" + } + } + } + ], + "outputArtifacts": [], + "artifactCredentials": { + "accessKeyId": "AKIAIOSFODNN7EXAMPLE", + "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=" + }, + "continuationToken": "A continuation token if continuing job" + } + } +} diff --git a/packages/parser/tests/events/codePipelineEventData.json b/packages/parser/tests/events/codePipelineEventData.json new file mode 100644 index 0000000000..7552f19ca9 --- /dev/null +++ b/packages/parser/tests/events/codePipelineEventData.json @@ -0,0 +1,46 @@ +{ + "CodePipeline.job": { + "id": "c0d76431-b0e7-xmpl-97e3-e8ee786eb6f6", + "accountId": "123456789012", + "data": { + "actionConfiguration": { + "configuration": { + "FunctionName": "my-function", + "UserParameters": "{\"KEY\": \"VALUE\"}" + } + }, + "inputArtifacts": [ + { + "name": "my-pipeline-SourceArtifact", + "revision": "e0c7xmpl2308ca3071aa7bab414de234ab52eea", + "location": { + "type": "S3", + "s3Location": { + "bucketName": "us-west-2-123456789012-my-pipeline", + "objectKey": "my-pipeline/test-api-2/TdOSFRV" + } + } + } + ], + "outputArtifacts": [ + { + "name": "invokeOutput", + "revision": null, + "location": { + "type": "S3", + "s3Location": { + "bucketName": "us-west-2-123456789012-my-pipeline", + "objectKey": "my-pipeline/invokeOutp/D0YHsJn" + } + } + } + ], + "artifactCredentials": { + "accessKeyId": "AKIAIOSFODNN7EXAMPLE", + "secretAccessKey": "6CGtmAa3lzWtV7a...", + "sessionToken": "IQoJb3JpZ2luX2VjEA...", + "expirationTime": 1575493418000 + } + } + } +} diff --git a/packages/parser/tests/events/codePipelineEventEmptyUserParameters.json b/packages/parser/tests/events/codePipelineEventEmptyUserParameters.json new file mode 100644 index 0000000000..1a0dec6a15 --- /dev/null +++ b/packages/parser/tests/events/codePipelineEventEmptyUserParameters.json @@ -0,0 +1,32 @@ +{ + "CodePipeline.job": { + "id": "11111111-abcd-1111-abcd-111111abcdef", + "accountId": "111111111111", + "data": { + "actionConfiguration": { + "configuration": { + "FunctionName": "MyLambdaFunctionForAWSCodePipeline" + } + }, + "inputArtifacts": [ + { + "name": "ArtifactName", + "revision": null, + "location": { + "type": "S3", + "s3Location": { + "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", + "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip" + } + } + } + ], + "outputArtifacts": [], + "artifactCredentials": { + "accessKeyId": "AKIAIOSFODNN7EXAMPLE", + "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=" + } + } + } +} diff --git a/packages/parser/tests/events/codePipelineEventWithEncryptionKey.json b/packages/parser/tests/events/codePipelineEventWithEncryptionKey.json new file mode 100644 index 0000000000..e4a8528e14 --- /dev/null +++ b/packages/parser/tests/events/codePipelineEventWithEncryptionKey.json @@ -0,0 +1,38 @@ +{ + "CodePipeline.job": { + "id": "11111111-abcd-1111-abcd-111111abcdef", + "accountId": "111111111111", + "data": { + "actionConfiguration": { + "configuration": { + "FunctionName": "MyLambdaFunctionForAWSCodePipeline", + "UserParameters": "some-input-such-as-a-URL" + } + }, + "inputArtifacts": [ + { + "name": "ArtifactName", + "revision": null, + "location": { + "type": "S3", + "s3Location": { + "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890", + "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip" + } + } + } + ], + "outputArtifacts": [], + "artifactCredentials": { + "accessKeyId": "AKIAIOSFODNN7EXAMPLE", + "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE=" + }, + "continuationToken": "A continuation token if continuing job", + "encryptionKey": { + "id": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", + "type": "KMS" + } + } + } +} diff --git a/packages/parser/tests/events/cognitoCreateAuthChallengeEvent.json b/packages/parser/tests/events/cognitoCreateAuthChallengeEvent.json new file mode 100644 index 0000000000..ad018ae082 --- /dev/null +++ b/packages/parser/tests/events/cognitoCreateAuthChallengeEvent.json @@ -0,0 +1,29 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "CreateAuthChallenge_Authentication", + "request": { + "userAttributes": { + "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", + "email_verified": "true", + "name": "First Last", + "email": "create-auth@mail.com" + }, + "challengeName": "PASSWORD_VERIFIER", + "session" : [ + { + "challengeName": "CUSTOM_CHALLENGE", + "challengeResult": true, + "challengeMetadata": "CAPTCHA_CHALLENGE" + } + ], + "userNotFound": false + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoCustomMessageEvent.json b/packages/parser/tests/events/cognitoCustomMessageEvent.json new file mode 100644 index 0000000000..8652c3bff4 --- /dev/null +++ b/packages/parser/tests/events/cognitoCustomMessageEvent.json @@ -0,0 +1,20 @@ +{ + "version": "1", + "triggerSource": "CustomMessage_AdminCreateUser", + "region": "region", + "userPoolId": "userPoolId", + "userName": "userName", + "callerContext": { + "awsSdk": "awsSdkVersion", + "clientId": "clientId" + }, + "request": { + "userAttributes": { + "phone_number_verified": false, + "email_verified": true + }, + "codeParameter": "####", + "usernameParameter": "username" + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoDefineAuthChallengeEvent.json b/packages/parser/tests/events/cognitoDefineAuthChallengeEvent.json new file mode 100644 index 0000000000..80ea5ac2d9 --- /dev/null +++ b/packages/parser/tests/events/cognitoDefineAuthChallengeEvent.json @@ -0,0 +1,32 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "DefineAuthChallenge_Authentication", + "request": { + "userAttributes": { + "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", + "email_verified": "true", + "name": "First Last", + "email": "define-auth@mail.com" + }, + "session" : [ + { + "challengeName": "PASSWORD_VERIFIER", + "challengeResult": true + }, + { + "challengeName": "CUSTOM_CHALLENGE", + "challengeResult": true, + "challengeMetadata": "CAPTCHA_CHALLENGE" + } + ], + "userNotFound": true + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoPostAuthenticationEvent.json b/packages/parser/tests/events/cognitoPostAuthenticationEvent.json new file mode 100644 index 0000000000..d34b18eeba --- /dev/null +++ b/packages/parser/tests/events/cognitoPostAuthenticationEvent.json @@ -0,0 +1,18 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "PostAuthentication_Authentication", + "request": { + "newDeviceUsed": true, + "userAttributes": { + "email": "post-auth@mail.com" + } + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoPostConfirmationEvent.json b/packages/parser/tests/events/cognitoPostConfirmationEvent.json new file mode 100644 index 0000000000..e88f98150c --- /dev/null +++ b/packages/parser/tests/events/cognitoPostConfirmationEvent.json @@ -0,0 +1,18 @@ +{ + "version": "string", + "triggerSource": "PostConfirmation_ConfirmSignUp", + "region": "us-east-1", + "userPoolId": "string", + "userName": "userName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "request": { + "userAttributes": { + "email": "user@example.com", + "email_verified": true + } + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoPreAuthenticationEvent.json b/packages/parser/tests/events/cognitoPreAuthenticationEvent.json new file mode 100644 index 0000000000..661fea6372 --- /dev/null +++ b/packages/parser/tests/events/cognitoPreAuthenticationEvent.json @@ -0,0 +1,20 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "PreAuthentication_Authentication", + "request": { + "userAttributes": { + "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", + "email_verified": "true", + "name": "First Last", + "email": "pre-auth@mail.com" + } + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoPreSignUpEvent.json b/packages/parser/tests/events/cognitoPreSignUpEvent.json new file mode 100644 index 0000000000..feb4eba25d --- /dev/null +++ b/packages/parser/tests/events/cognitoPreSignUpEvent.json @@ -0,0 +1,18 @@ +{ + "version": "string", + "triggerSource": "PreSignUp_SignUp", + "region": "us-east-1", + "userPoolId": "string", + "userName": "userName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "request": { + "userAttributes": { + "email": "user@example.com", + "phone_number": "+12065550100" + } + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoPreTokenGenerationEvent.json b/packages/parser/tests/events/cognitoPreTokenGenerationEvent.json new file mode 100644 index 0000000000..f5ee69e0d2 --- /dev/null +++ b/packages/parser/tests/events/cognitoPreTokenGenerationEvent.json @@ -0,0 +1,25 @@ +{ + "version": "1", + "triggerSource": "TokenGeneration_Authentication", + "region": "us-west-2", + "userPoolId": "us-west-2_example", + "userName": "testqq", + "callerContext": { + "awsSdkVersion": "aws-sdk-unknown-unknown", + "clientId": "71ghuul37mresr7h373b704tua" + }, + "request": { + "userAttributes": { + "sub": "0b0a57c5-f013-426a-81a1-f8ffbfba21f0", + "email_verified": "true", + "cognito:user_status": "CONFIRMED", + "email": "test@mail.com" + }, + "groupConfiguration": { + "groupsToOverride": [], + "iamRolesToOverride": [], + "preferredRole": null + } + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoUserMigrationEvent.json b/packages/parser/tests/events/cognitoUserMigrationEvent.json new file mode 100644 index 0000000000..2eae4e6618 --- /dev/null +++ b/packages/parser/tests/events/cognitoUserMigrationEvent.json @@ -0,0 +1,15 @@ +{ + "version": "string", + "triggerSource": "UserMigration_Authentication", + "region": "us-east-1", + "userPoolId": "string", + "userName": "userName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "request": { + "password": "password" + }, + "response": {} +} diff --git a/packages/parser/tests/events/cognitoVerifyAuthChallengeResponseEvent.json b/packages/parser/tests/events/cognitoVerifyAuthChallengeResponseEvent.json new file mode 100644 index 0000000000..2ebcdb5c27 --- /dev/null +++ b/packages/parser/tests/events/cognitoVerifyAuthChallengeResponseEvent.json @@ -0,0 +1,28 @@ +{ + "version": "1", + "region": "us-east-1", + "userPoolId": "us-east-1_example", + "userName": "UserName", + "callerContext": { + "awsSdkVersion": "awsSdkVersion", + "clientId": "clientId" + }, + "triggerSource": "VerifyAuthChallengeResponse_Authentication", + "request": { + "userAttributes": { + "sub": "4A709A36-7D63-4785-829D-4198EF10EBDA", + "email_verified": "true", + "name": "First Last", + "email": "verify-auth@mail.com" + }, + "privateChallengeParameters": { + "answer": "challengeAnswer" + }, + "clientMetadata" : { + "foo": "value" + }, + "challengeAnswer": "challengeAnswer", + "userNotFound": true + }, + "response": {} +} diff --git a/packages/parser/tests/events/connectContactFlowEventAll.json b/packages/parser/tests/events/connectContactFlowEventAll.json new file mode 100644 index 0000000000..5850649b6e --- /dev/null +++ b/packages/parser/tests/events/connectContactFlowEventAll.json @@ -0,0 +1,41 @@ +{ + "Name": "ContactFlowEvent", + "Details": { + "ContactData": { + "Attributes": { + "Language": "en-US" + }, + "Channel": "VOICE", + "ContactId": "5ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "CustomerEndpoint": { + "Address": "+11234567890", + "Type": "TELEPHONE_NUMBER" + }, + "InitialContactId": "5ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "InitiationMethod": "API", + "InstanceARN": "arn:aws:connect:eu-central-1:123456789012:instance/9308c2a1-9bc6-4cea-8290-6c0b4a6d38fa", + "MediaStreams": { + "Customer": { + "Audio": { + "StartFragmentNumber": "91343852333181432392682062622220590765191907586", + "StartTimestamp": "1565781909613", + "StreamARN": "arn:aws:kinesisvideo:eu-central-1:123456789012:stream/connect-contact-a3d73b84-ce0e-479a-a9dc-5637c9d30ac9/1565272947806" + } + } + }, + "PreviousContactId": "5ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "Queue": { + "ARN": "arn:aws:connect:eu-central-1:123456789012:instance/9308c2a1-9bc6-4cea-8290-6c0b4a6d38fa/queue/5cba7cbf-1ecb-4b6d-b8bd-fe91079b3fc8", + "Name": "QueueOne" + }, + "SystemEndpoint": { + "Address": "+11234567890", + "Type": "TELEPHONE_NUMBER" + } + }, + "Parameters": { + "ParameterOne": "One", + "ParameterTwo": "Two" + } + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/connectContactFlowEventMin.json b/packages/parser/tests/events/connectContactFlowEventMin.json new file mode 100644 index 0000000000..9cc22d59c3 --- /dev/null +++ b/packages/parser/tests/events/connectContactFlowEventMin.json @@ -0,0 +1,27 @@ +{ + "Name": "ContactFlowEvent", + "Details": { + "ContactData": { + "Attributes": {}, + "Channel": "VOICE", + "ContactId": "5ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "CustomerEndpoint": null, + "InitialContactId": "5ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "InitiationMethod": "API", + "InstanceARN": "arn:aws:connect:eu-central-1:123456789012:instance/9308c2a1-9bc6-4cea-8290-6c0b4a6d38fa", + "MediaStreams": { + "Customer": { + "Audio": { + "StartFragmentNumber": null, + "StartTimestamp": null, + "StreamARN": null + } + } + }, + "PreviousContactId": "5ca32fbd-8f92-46af-92a5-6b0f970f0efe", + "Queue": null, + "SystemEndpoint": null + }, + "Parameters": {} + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/dynamoStreamEvent.json b/packages/parser/tests/events/dynamoStreamEvent.json new file mode 100644 index 0000000000..16009a7a95 --- /dev/null +++ b/packages/parser/tests/events/dynamoStreamEvent.json @@ -0,0 +1,65 @@ +{ + "Records": [ + { + "eventID": "1", + "eventVersion": "1.0", + "dynamodb": { + "ApproximateCreationDateTime": 1693997155.0, + "Keys": { + "Id": { + "N": "101" + } + }, + "NewImage": { + "Message": { + "S": "New item!" + }, + "Id": { + "N": "101" + } + }, + "StreamViewType": "NEW_AND_OLD_IMAGES", + "SequenceNumber": "111", + "SizeBytes": 26 + }, + "awsRegion": "us-west-2", + "eventName": "INSERT", + "eventSourceARN": "eventsource_arn", + "eventSource": "aws:dynamodb" + }, + { + "eventID": "2", + "eventVersion": "1.0", + "dynamodb": { + "OldImage": { + "Message": { + "S": "New item!" + }, + "Id": { + "N": "101" + } + }, + "SequenceNumber": "222", + "Keys": { + "Id": { + "N": "101" + } + }, + "SizeBytes": 59, + "NewImage": { + "Message": { + "S": "This item has changed" + }, + "Id": { + "N": "101" + } + }, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "awsRegion": "us-west-2", + "eventName": "MODIFY", + "eventSourceARN": "source_arn", + "eventSource": "aws:dynamodb" + } + ] +} diff --git a/packages/parser/tests/events/eventBridgeEvent.json b/packages/parser/tests/events/eventBridgeEvent.json new file mode 100644 index 0000000000..65872cf9a3 --- /dev/null +++ b/packages/parser/tests/events/eventBridgeEvent.json @@ -0,0 +1,17 @@ +{ + "version": "0", + "id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718", + "detail-type": "EC2 Instance State-change Notification", + "source": "aws.ec2", + "account": "111122223333", + "time": "2017-12-22T18:43:48Z", + "region": "us-west-1", + "resources": [ + "arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0" + ], + "detail": { + "instance_id": "i-1234567890abcdef0", + "state": "terminated" + }, + "replay-name": "replay_archive" +} diff --git a/packages/parser/tests/events/kafkaEventMsk.json b/packages/parser/tests/events/kafkaEventMsk.json new file mode 100644 index 0000000000..5a35b89680 --- /dev/null +++ b/packages/parser/tests/events/kafkaEventMsk.json @@ -0,0 +1,35 @@ +{ + "eventSource":"aws:kafka", + "eventSourceArn":"arn:aws:kafka:us-east-1:0123456789019:cluster/SalesCluster/abcd1234-abcd-cafe-abab-9876543210ab-4", + "bootstrapServers":"b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", + "records":{ + "mytopic-0":[ + { + "topic":"mytopic", + "partition":0, + "offset":15, + "timestamp":1545084650987, + "timestampType":"CREATE_TIME", + "key":"cmVjb3JkS2V5", + "value":"eyJrZXkiOiJ2YWx1ZSJ9", + "headers":[ + { + "headerKey":[ + 104, + 101, + 97, + 100, + 101, + 114, + 86, + 97, + 108, + 117, + 101 + ] + } + ] + } + ] + } +} diff --git a/packages/parser/tests/events/kafkaEventSelfManaged.json b/packages/parser/tests/events/kafkaEventSelfManaged.json new file mode 100644 index 0000000000..22985dd11d --- /dev/null +++ b/packages/parser/tests/events/kafkaEventSelfManaged.json @@ -0,0 +1,34 @@ +{ + "eventSource":"aws:SelfManagedKafka", + "bootstrapServers":"b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092", + "records":{ + "mytopic-0":[ + { + "topic":"mytopic", + "partition":0, + "offset":15, + "timestamp":1545084650987, + "timestampType":"CREATE_TIME", + "key":"cmVjb3JkS2V5", + "value":"eyJrZXkiOiJ2YWx1ZSJ9", + "headers":[ + { + "headerKey":[ + 104, + 101, + 97, + 100, + 101, + 114, + 86, + 97, + 108, + 117, + 101 + ] + } + ] + } + ] + } +} diff --git a/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json b/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json new file mode 100644 index 0000000000..6cdd8e8a5b --- /dev/null +++ b/packages/parser/tests/events/kinesisFirehoseKinesisEvent.json @@ -0,0 +1,32 @@ +{ + "invocationId": "2b4d1ad9-2f48-94bd-a088-767c317e994a", + "sourceKinesisStreamArn":"arn:aws:kinesis:us-east-1:123456789012:stream/kinesis-source", + "deliveryStreamArn": "arn:aws:firehose:us-east-2:123456789012:deliverystream/delivery-stream-name", + "region": "us-east-2", + "records": [ + { + "data": "SGVsbG8gV29ybGQ=", + "recordId": "record1", + "approximateArrivalTimestamp": 1664028820148, + "kinesisRecordMetadata": { + "shardId": "shardId-000000000000", + "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c317a", + "approximateArrivalTimestamp": 1664028820148, + "sequenceNumber": "49546986683135544286507457936321625675700192471156785154", + "subsequenceNumber": 0 + } + }, + { + "data": "eyJIZWxsbyI6ICJXb3JsZCJ9", + "recordId": "record2", + "approximateArrivalTimestamp": 1664028793294, + "kinesisRecordMetadata": { + "shardId": "shardId-000000000001", + "partitionKey": "4d1ad2b9-24f8-4b9d-a088-76e9947c318a", + "approximateArrivalTimestamp": 1664028793294, + "sequenceNumber": "49546986683135544286507457936321625675700192471156785155", + "subsequenceNumber": 0 + } + } + ] +} diff --git a/packages/parser/tests/events/kinesisFirehosePutEvent.json b/packages/parser/tests/events/kinesisFirehosePutEvent.json new file mode 100644 index 0000000000..f3e0719071 --- /dev/null +++ b/packages/parser/tests/events/kinesisFirehosePutEvent.json @@ -0,0 +1,17 @@ +{ + "invocationId": "2b4d1ad9-2f48-94bd-a088-767c317e994a", + "deliveryStreamArn": "arn:aws:firehose:us-east-2:123456789012:deliverystream/delivery-stream-name", + "region": "us-east-2", + "records": [ + { + "recordId": "record1", + "approximateArrivalTimestamp": 1664029185290, + "data": "SGVsbG8gV29ybGQ=" + }, + { + "recordId": "record2", + "approximateArrivalTimestamp": 1664029186945, + "data": "eyJIZWxsbyI6ICJXb3JsZCJ9" + } + ] + } diff --git a/packages/parser/tests/events/kinesisFirehoseSQSEvent.json b/packages/parser/tests/events/kinesisFirehoseSQSEvent.json new file mode 100644 index 0000000000..bea267c420 --- /dev/null +++ b/packages/parser/tests/events/kinesisFirehoseSQSEvent.json @@ -0,0 +1,12 @@ +{ + "invocationId": "556b67a3-48fc-4385-af49-e133aade9cb9", + "deliveryStreamArn": "arn:aws:firehose:us-east-1:123456789012:deliverystream/PUT-S3-tdyyE", + "region": "us-east-1", + "records": [ + { + "recordId": "49640912821178817833517986466168945147170627572855734274000000", + "approximateArrivalTimestamp": 1684864917398, + "data": "eyJtZXNzYWdlSWQiOiI1YWI4MDdkNC01NjQ0LTRjNTUtOTdhMy00NzM5NjYzNWFjNzQiLCJyZWNlaXB0SGFuZGxlIjoiQVFFQndKbkt5ckhpZ1VNWmo2cllpZ0NneGxhUzNTTHkwYS4uLiIsImJvZHkiOiJUZXN0IG1lc3NhZ2UuIiwiYXR0cmlidXRlcyI6eyJBcHByb3hpbWF0ZVJlY2VpdmVDb3VudCI6IjEiLCJTZW50VGltZXN0YW1wIjoiMTY4NDg2NDg1MjQ5MSIsIlNlbmRlcklkIjoiQUlEQUlFTlFaSk9MTzIzWVZKNFZPIiwiQXBwcm94aW1hdGVGaXJzdFJlY2VpdmVUaW1lc3RhbXAiOiIxNjg0ODY0ODcyNDkxIn0sIm1lc3NhZ2VBdHRyaWJ1dGVzIjp7fSwibWQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6bnVsbCwibWQ1T2ZCb2R5IjoiYzhiNmJjNjBjOGI4YjNhOTA0ZTQ1YzFmYWJkZjUyM2QiLCJldmVudFNvdXJjZSI6ImF3czpzcXMiLCJldmVudFNvdXJjZUFSTiI6ImFybjphd3M6c3FzOnVzLWVhc3QtMToyMDA5ODQxMTIzODY6U05TIiwiYXdzUmVnaW9uIjoidXMtZWFzdC0xIn0K" + } + ] +} diff --git a/packages/parser/tests/events/kinesisStreamCloudWatchLogsEvent.json b/packages/parser/tests/events/kinesisStreamCloudWatchLogsEvent.json new file mode 100644 index 0000000000..a9a6959f90 --- /dev/null +++ b/packages/parser/tests/events/kinesisStreamCloudWatchLogsEvent.json @@ -0,0 +1,36 @@ +{ + "Records": [ + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "da10bf66b1f54bff5d96eae99149ad1f", + "sequenceNumber": "49635052289529725553291405521504870233219489715332317186", + "data": "H4sIAAAAAAAAAK2Sa2vbMBSG/4ox+xg3Oror39IlvaztVmJv7WjCUGwl8+ZLZstts5L/vuOsZYUyWGEgJHiP9J7nvOghLF3b2rVLthsXjsLJOBl/uZjG8fh4Gg7C+q5yDcqUAWcSONHEoFzU6+Om7jZYGdq7dljYcpnZ4cZHwLWOJl1Zbs/r9cR6e9RVqc/rKlpXV9eXt+fy27vt8W+L2DfOlr07oXQIMAQyvHlzPk6mcbKgciktF5lQfMU5dZZqzrShLF2uFC60aLtlmzb5prc/ygvvmjYc3YRPFG+LusuurE+/Ikqb1Gd55dq8jV+8isT6+317Rk42J5PTcLFnm966yvd2D2GeISJTYIwCJSQ1BE9OtWZCABWaKMIJAMdDMyU5MYZLhmkxBhQxfY4Re1tiWiAlBsgIVQTE4Cl6tI+T8SwJZu5Hh1dPs1FApOMSDI9WVKmIC+4irTMWQZYpx7QkztrgE06MU4yCx9DmVbgbvABmQJTGtkYAB0NwEwyYQUBpqEFuSbkGrThTRKi/AlP+HHj6fvJa3P9Ap/+Rbja9/PD6POd+0jXW7xM1B8CDsp37w7woXBb8qQDZ6xeurJttEOc/HWpUBxeHKNr74LHwsXXYlsm9flrl/rmFIQeS7m3m1fVs/DlIGpu6nhMiyWQGXNKIMbcCIgkhElKbaZnZpYJUz33s1iV+z/6+StMlR3yphHNcCyxiNEXf2zed6xuEu8XuF2wb6krnAwAA", + "approximateArrivalTimestamp": 1668093033.744 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000000:49635052289529725553291405521504870233219489715332317186", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::231436140809:role/pt-1488-CloudWatchKinesisLogsFunctionRole-1M4G2TIWIE49", + "awsRegion": "eu-west-1", + "eventSourceARN": "arn:aws:kinesis:eu-west-1:231436140809:stream/pt-1488-KinesisStreamCloudWatchLogs-D8tHs0im0aJG" + }, + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "cf4c4c2c9a49bdfaf58d7dbbc2b06081", + "sequenceNumber": "49635052289529725553291405520881064510298312199003701250", + "data": "H4sIAAAAAAAAAK2SW2/TQBCF/4pl8ViTvc7u5i0laVraQhUbWtREaG1PgsGXYK/bhqr/nXVoBRIgUYnXc2bPfHO092GFXWc3mOy2GI7D6SSZfDyfxfFkPgsPwua2xtbLjFPBgQqiifFy2WzmbdNvvTOyt92otFWa29HWRVRoHU37qtqdNZupdfaorzNXNHW0qS+vLm7O4PPr3fxHROxatNWQThgbUTqiZHT94mySzOJkBUqYLOWY8ZQLbaTRkEvDciUYzWzKfETXp13WFtsh/qgoHbZdOL4OnyhelU2fX1qXffIoXdKcFjV2RRf/9iqSmy933Sk53h5PT8LVnm12g7Ub4u7DIveIXFFjFNGUKUlAaMY0EUJKLjkQbxhKGCWeknMKoAGUkYoJ7TFd4St2tvJtDRYxDAg3VB08Ve/j42SySIIFfu396Ek+DkS+xkwAiYhM00isgUV6jXmEMrM5EmMsh+C9v9hfMQ4eS1vW4cPBH4CZVpoTJkEIAp5RUMo8vGFae3JNCCdUccMVgPw7sP4VePZm+lzc/0AH/0i3mF28fX6fSzftW+v2jZKXRgVVt3SHRVliHvx06F4+x6ppd0FcfEMvMR2cH3rR3gWPxrsO/Vau9vqyvlpMPgRJazMcYGgEHHLKBhLGJaBA0JLxNc0JppoS9Cwxbir/B4d5QDBAQSnfFFGp8aa/vxw2uLbHYUH4sHr4Dj5RJxfMAwAA", + "approximateArrivalTimestamp": 1668092612.992 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000000:49635052289529725553291405520881064510298312199003701250", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::231436140809:role/pt-1488-CloudWatchKinesisLogsFunctionRole-1M4G2TIWIE49", + "awsRegion": "eu-west-1", + "eventSourceARN": "arn:aws:kinesis:eu-west-1:231436140809:stream/pt-1488-KinesisStreamCloudWatchLogs-D8tHs0im0aJG" + } + ] +} \ No newline at end of file diff --git a/packages/parser/tests/events/kinesisStreamEvent.json b/packages/parser/tests/events/kinesisStreamEvent.json new file mode 100644 index 0000000000..ef8e209638 --- /dev/null +++ b/packages/parser/tests/events/kinesisStreamEvent.json @@ -0,0 +1,36 @@ +{ + "Records": [ + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "1", + "sequenceNumber": "49590338271490256608559692538361571095921575989136588898", + "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==", + "approximateArrivalTimestamp": 1545084650.987 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role", + "awsRegion": "us-east-2", + "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream" + }, + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "1", + "sequenceNumber": "49590338271490256608559692540925702759324208523137515618", + "data": "VGhpcyBpcyBvbmx5IGEgdGVzdC4=", + "approximateArrivalTimestamp": 1545084711.166 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000006:49590338271490256608559692540925702759324208523137515618", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role", + "awsRegion": "us-east-2", + "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream" + } + ] +} diff --git a/packages/parser/tests/events/kinesisStreamEventOneRecord.json b/packages/parser/tests/events/kinesisStreamEventOneRecord.json new file mode 100644 index 0000000000..05fe2d297a --- /dev/null +++ b/packages/parser/tests/events/kinesisStreamEventOneRecord.json @@ -0,0 +1,20 @@ +{ + "Records": [ + { + "kinesis": { + "kinesisSchemaVersion": "1.0", + "partitionKey": "1", + "sequenceNumber": "49590338271490256608559692538361571095921575989136588898", + "data": "eyJtZXNzYWdlIjogInRlc3QgbWVzc2FnZSIsICJ1c2VybmFtZSI6ICJ0ZXN0In0=", + "approximateArrivalTimestamp": 1545084650.987 + }, + "eventSource": "aws:kinesis", + "eventVersion": "1.0", + "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898", + "eventName": "aws:kinesis:record", + "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role", + "awsRegion": "us-east-2", + "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream" + } + ] +} diff --git a/packages/parser/tests/events/lambdaFunctionUrlEvent.json b/packages/parser/tests/events/lambdaFunctionUrlEvent.json new file mode 100644 index 0000000000..da5c133e6f --- /dev/null +++ b/packages/parser/tests/events/lambdaFunctionUrlEvent.json @@ -0,0 +1,47 @@ +{ + "version":"2.0", + "routeKey":"$default", + "rawPath":"/", + "rawQueryString":"", + "headers":{ + "sec-fetch-mode":"navigate", + "x-amzn-tls-version":"TLSv1.2", + "sec-fetch-site":"cross-site", + "accept-language":"pt-BR,pt;q=0.9", + "x-forwarded-proto":"https", + "x-forwarded-port":"443", + "x-forwarded-for":"123.123.123.123", + "sec-fetch-user":"?1", + "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", + "x-amzn-tls-cipher-suite":"ECDHE-RSA-AES128-GCM-SHA256", + "sec-ch-ua":"\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"", + "sec-ch-ua-mobile":"?0", + "x-amzn-trace-id":"Root=1-62ecd163-5f302e550dcde3b12402207d", + "sec-ch-ua-platform":"\"Linux\"", + "host":".lambda-url.us-east-1.on.aws", + "upgrade-insecure-requests":"1", + "cache-control":"max-age=0", + "accept-encoding":"gzip, deflate, br", + "sec-fetch-dest":"document", + "user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36" + }, + "requestContext":{ + "accountId":"anonymous", + "apiId":"", + "domainName":".lambda-url.us-east-1.on.aws", + "domainPrefix":"", + "http":{ + "method":"GET", + "path":"/", + "protocol":"HTTP/1.1", + "sourceIp":"123.123.123.123", + "userAgent":"agent" + }, + "requestId":"id", + "routeKey":"$default", + "stage":"$default", + "time":"05/Aug/2022:08:14:39 +0000", + "timeEpoch":1659687279885 + }, + "isBase64Encoded":false +} diff --git a/packages/parser/tests/events/lambdaFunctionUrlEventPathTrailingSlash.json b/packages/parser/tests/events/lambdaFunctionUrlEventPathTrailingSlash.json new file mode 100644 index 0000000000..b1f8226518 --- /dev/null +++ b/packages/parser/tests/events/lambdaFunctionUrlEventPathTrailingSlash.json @@ -0,0 +1,52 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path/", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "header1": "value1", + "header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "", + "authentication": null, + "authorizer": { + "iam": { + "accessKey": "AKIA...", + "accountId": "111122223333", + "callerId": "AIDA...", + "cognitoIdentity": null, + "principalOrgId": null, + "userArn": "arn:aws:iam::111122223333:user/example-user", + "userId": "AIDA..." + } + }, + "domainName": ".lambda-url.us-west-2.on.aws", + "domainPrefix": "", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "123.123.123.123", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "body": "Hello from client!", + "pathParameters": null, + "isBase64Encoded": false, + "stageVariables": null + } \ No newline at end of file diff --git a/packages/parser/tests/events/lambdaFunctionUrlIAMEvent.json b/packages/parser/tests/events/lambdaFunctionUrlIAMEvent.json new file mode 100644 index 0000000000..bf52342b66 --- /dev/null +++ b/packages/parser/tests/events/lambdaFunctionUrlIAMEvent.json @@ -0,0 +1,52 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "header1": "value1", + "header2": "value1,value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext": { + "accountId": "123456789012", + "apiId": "", + "authentication": null, + "authorizer": { + "iam": { + "accessKey": "AKIA...", + "accountId": "111122223333", + "callerId": "AIDA...", + "cognitoIdentity": null, + "principalOrgId": null, + "userArn": "arn:aws:iam::111122223333:user/example-user", + "userId": "AIDA..." + } + }, + "domainName": ".lambda-url.us-west-2.on.aws", + "domainPrefix": "", + "http": { + "method": "POST", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "123.123.123.123", + "userAgent": "agent" + }, + "requestId": "id", + "routeKey": "$default", + "stage": "$default", + "time": "12/Mar/2020:19:03:58 +0000", + "timeEpoch": 1583348638390 + }, + "body": "Hello from client!", + "pathParameters": null, + "isBase64Encoded": false, + "stageVariables": null +} diff --git a/packages/parser/tests/events/rabbitMQEvent.json b/packages/parser/tests/events/rabbitMQEvent.json new file mode 100644 index 0000000000..e4259555a8 --- /dev/null +++ b/packages/parser/tests/events/rabbitMQEvent.json @@ -0,0 +1,51 @@ +{ + "eventSource": "aws:rmq", + "eventSourceArn": "arn:aws:mq:us-west-2:112556298976:broker:pizzaBroker:b-9bcfa592-423a-4942-879d-eb284b418fc8", + "rmqMessagesByQueue": { + "pizzaQueue::/": [ + { + "basicProperties": { + "contentType": "text/plain", + "contentEncoding": null, + "headers": { + "header1": { + "bytes": [ + 118, + 97, + 108, + 117, + 101, + 49 + ] + }, + "header2": { + "bytes": [ + 118, + 97, + 108, + 117, + 101, + 50 + ] + }, + "numberInHeader": 10 + }, + "deliveryMode": 1, + "priority": 34, + "correlationId": null, + "replyTo": null, + "expiration": "60000", + "messageId": null, + "timestamp": "Jan 1, 1970, 12:33:41 AM", + "type": null, + "userId": "AIDACKCEVSQ6C2EXAMPLE", + "appId": null, + "clusterId": null, + "bodySize": 80 + }, + "redelivered": false, + "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ==" + } + ] + } +} diff --git a/packages/parser/tests/events/s3Event.json b/packages/parser/tests/events/s3Event.json new file mode 100644 index 0000000000..4558dc3c9e --- /dev/null +++ b/packages/parser/tests/events/s3Event.json @@ -0,0 +1,38 @@ +{ + "Records": [ + { + "eventVersion": "2.1", + "eventSource": "aws:s3", + "awsRegion": "us-east-2", + "eventTime": "2019-09-03T19:37:27.192Z", + "eventName": "ObjectCreated:Put", + "userIdentity": { + "principalId": "AWS:AIDAINPONIXQXHT3IKHL2" + }, + "requestParameters": { + "sourceIPAddress": "205.255.255.255" + }, + "responseElements": { + "x-amz-request-id": "D82B88E5F771F645", + "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=" + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1", + "bucket": { + "name": "lambda-artifacts-deafc19498e3f2df", + "ownerIdentity": { + "principalId": "A3I5XTEXAMAI3E" + }, + "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df" + }, + "object": { + "key": "b21b84d653bb07b05b1e6b33684dc11b", + "size": 1305107, + "eTag": "b21b84d653bb07b05b1e6b33684dc11b", + "sequencer": "0C0F6F405D6ED209E1" + } + } + } + ] +} diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json b/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json new file mode 100644 index 0000000000..5cc8f2f402 --- /dev/null +++ b/packages/parser/tests/events/s3EventBridgeNotificationObjectCreatedEvent.json @@ -0,0 +1,28 @@ +{ + "version": "0", + "id": "f5f1e65c-dc3a-93ca-6c1e-b1647eac7963", + "detail-type": "Object Created", + "source": "aws.s3", + "account": "123456789012", + "time": "2023-03-08T17:50:14Z", + "region": "eu-west-1", + "resources": [ + "arn:aws:s3:::example-bucket" + ], + "detail": { + "version": "0", + "bucket": { + "name": "example-bucket" + }, + "object": { + "key": "IMG_m7fzo3.jpg", + "size": 184662, + "etag": "4e68adba0abe2dc8653dc3354e14c01d", + "sequencer": "006408CAD69598B05E" + }, + "request-id": "57H08PA84AB1JZW0", + "requester": "123456789012", + "source-ip-address": "34.252.34.74", + "reason": "PutObject" + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json b/packages/parser/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json new file mode 100644 index 0000000000..af52ee2fef --- /dev/null +++ b/packages/parser/tests/events/s3EventBridgeNotificationObjectDeletedEvent.json @@ -0,0 +1,29 @@ +{ + "version": "0", + "id": "2ee9cc15-d022-99ea-1fb8-1b1bac4850f9", + "detail-type": "Object Deleted", + "source": "aws.s3", + "account": "111122223333", + "time": "2021-11-12T00:00:00Z", + "region": "ca-central-1", + "resources": [ + "arn:aws:s3:::example-bucket" + ], + "detail": { + "version": "0", + "bucket": { + "name": "example-bucket" + }, + "object": { + "key": "IMG_m7fzo3.jpg", + "size": 184662, + "etag": "4e68adba0abe2dc8653dc3354e14c01d", + "sequencer": "006408CAD69598B05E" + }, + "request-id": "0BH729840619AG5K", + "requester": "123456789012", + "source-ip-address": "34.252.34.74", + "reason": "DeleteObject", + "deletion-type": "Delete Marker Created" + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectExpiredEvent.json b/packages/parser/tests/events/s3EventBridgeNotificationObjectExpiredEvent.json new file mode 100644 index 0000000000..ef506cc355 --- /dev/null +++ b/packages/parser/tests/events/s3EventBridgeNotificationObjectExpiredEvent.json @@ -0,0 +1,28 @@ +{ + "version": "0", + "id": "ad1de317-e409-eba2-9552-30113f8d88e3", + "detail-type": "Object Deleted", + "source": "aws.s3", + "account": "111122223333", + "time": "2021-11-12T00:00:00Z", + "region": "ca-central-1", + "resources": [ + "arn:aws:s3:::example-bucket" + ], + "detail": { + "version": "0", + "bucket": { + "name": "example-bucket" + }, + "object": { + "key": "IMG_m7fzo3.jpg", + "size": 184662, + "etag": "4e68adba0abe2dc8653dc3354e14c01d", + "sequencer": "006408CAD69598B05E" + }, + "request-id": "20EB74C14654DC47", + "requester": "s3.amazonaws.com", + "reason": "Lifecycle Expiration", + "deletion-type": "Delete Marker Created" + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/s3EventBridgeNotificationObjectRestoreCompletedEvent.json b/packages/parser/tests/events/s3EventBridgeNotificationObjectRestoreCompletedEvent.json new file mode 100644 index 0000000000..5a2e6a4f9e --- /dev/null +++ b/packages/parser/tests/events/s3EventBridgeNotificationObjectRestoreCompletedEvent.json @@ -0,0 +1,28 @@ +{ + "version": "0", + "id": "6924de0d-13e2-6bbf-c0c1-b903b753565e", + "detail-type": "Object Restore Completed", + "source": "aws.s3", + "account": "111122223333", + "time": "2021-11-12T00:00:00Z", + "region": "ca-central-1", + "resources": [ + "arn:aws:s3:::example-bucket" + ], + "detail": { + "version": "0", + "bucket": { + "name": "example-bucket" + }, + "object": { + "key": "IMG_m7fzo3.jpg", + "size": 184662, + "etag": "4e68adba0abe2dc8653dc3354e14c01d", + "sequencer": "006408CAD69598B05E" + }, + "request-id": "189F19CB7FB1B6A4", + "requester": "s3.amazonaws.com", + "restore-expiry-time": "2021-11-13T00:00:00Z", + "source-storage-class": "GLACIER" + } +} \ No newline at end of file diff --git a/packages/parser/tests/events/s3EventDecodedKey.json b/packages/parser/tests/events/s3EventDecodedKey.json new file mode 100644 index 0000000000..05f5ab5c4b --- /dev/null +++ b/packages/parser/tests/events/s3EventDecodedKey.json @@ -0,0 +1,40 @@ +{ + "Records": [ + { + "eventVersion": "2.0", + "eventSource": "aws:s3", + "awsRegion": "us-east-1", + "eventTime": "1970-01-01T00:00:00.123Z", + "eventName": "ObjectCreated:Put", + "userIdentity": { + "principalId": "EXAMPLE" + }, + "requestParameters": { + "sourceIPAddress": "127.0.0.1" + }, + "responseElements": { + "x-amz-request-id": "C3D13FE58DE4C810", + "x-amz-id-2": "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD" + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "testConfigRule", + "bucket": { + "name": "sourcebucket", + "ownerIdentity": { + "principalId": "EXAMPLE" + }, + "arn": "arn:aws:s3:::mybucket" + }, + "object": { + "key": "Happy%20Face.jpg", + "urlDecodedKey": "Happy Face.jpg", + "size": 1024, + "versionId": "version", + "eTag": "d41d8cd98f00b204e9800998ecf8427e", + "sequencer": "Happy Sequencer" + } + } + } + ] +} diff --git a/packages/parser/tests/events/s3EventDeleteObject.json b/packages/parser/tests/events/s3EventDeleteObject.json new file mode 100644 index 0000000000..3a607242f0 --- /dev/null +++ b/packages/parser/tests/events/s3EventDeleteObject.json @@ -0,0 +1,36 @@ +{ + "Records": [ + { + "eventVersion": "2.1", + "eventSource": "aws:s3", + "awsRegion": "us-east-2", + "eventTime": "2019-09-03T19:37:27.192Z", + "eventName": "ObjectRemoved:Delete", + "userIdentity": { + "principalId": "AWS:AIDAINPONIXQXHT3IKHL2" + }, + "requestParameters": { + "sourceIPAddress": "205.255.255.255" + }, + "responseElements": { + "x-amz-request-id": "D82B88E5F771F645", + "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=" + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1", + "bucket": { + "name": "lambda-artifacts-deafc19498e3f2df", + "ownerIdentity": { + "principalId": "A3I5XTEXAMAI3E" + }, + "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df" + }, + "object": { + "key": "b21b84d653bb07b05b1e6b33684dc11b", + "sequencer": "0C0F6F405D6ED209E1" + } + } + } + ] +} \ No newline at end of file diff --git a/packages/parser/tests/events/s3EventGlacier.json b/packages/parser/tests/events/s3EventGlacier.json new file mode 100644 index 0000000000..2fbc447b30 --- /dev/null +++ b/packages/parser/tests/events/s3EventGlacier.json @@ -0,0 +1,44 @@ +{ + "Records": [ + { + "eventVersion": "2.1", + "eventSource": "aws:s3", + "awsRegion": "us-east-2", + "eventTime": "2019-09-03T19:37:27.192Z", + "eventName": "ObjectCreated:Put", + "userIdentity": { + "principalId": "AWS:AIDAINPONIXQXHT3IKHL2" + }, + "requestParameters": { + "sourceIPAddress": "205.255.255.255" + }, + "responseElements": { + "x-amz-request-id": "D82B88E5F771F645", + "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=" + }, + "s3": { + "s3SchemaVersion": "1.0", + "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1", + "bucket": { + "name": "lambda-artifacts-deafc19498e3f2df", + "ownerIdentity": { + "principalId": "A3I5XTEXAMAI3E" + }, + "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df" + }, + "object": { + "key": "b21b84d653bb07b05b1e6b33684dc11b", + "size": 1305107, + "eTag": "b21b84d653bb07b05b1e6b33684dc11b", + "sequencer": "0C0F6F405D6ED209E1" + } + }, + "glacierEventData": { + "restoreEventData": { + "lifecycleRestorationExpiryTime": "1970-01-01T00:01:00.000Z", + "lifecycleRestoreStorageClass": "standard" + } + } + } + ] +} \ No newline at end of file diff --git a/packages/parser/tests/events/s3ObjectEventIAMUser.json b/packages/parser/tests/events/s3ObjectEventIAMUser.json new file mode 100644 index 0000000000..6be41c4352 --- /dev/null +++ b/packages/parser/tests/events/s3ObjectEventIAMUser.json @@ -0,0 +1,30 @@ +{ + "xAmzRequestId": "1a5ed718-5f53-471d-b6fe-5cf62d88d02a", + "getObjectContext": { + "inputS3Url": "https://myap-123412341234.s3-accesspoint.us-east-1.amazonaws.com/s3.txt?X-Amz-Security-Token=...", + "outputRoute": "io-iad-cell001", + "outputToken": "..." + }, + "configuration": { + "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:123412341234:accesspoint/myolap", + "supportingAccessPointArn": "arn:aws:s3:us-east-1:123412341234:accesspoint/myap", + "payload": "test" + }, + "userRequest": { + "url": "/s3.txt", + "headers": { + "Host": "myolap-123412341234.s3-object-lambda.us-east-1.amazonaws.com", + "Accept-Encoding": "identity", + "X-Amz-Content-SHA256": "e3b0c44297fc1c149afbf4c8995fb92427ae41e4649b934ca495991b7852b855" + } + }, + "userIdentity": { + "type": "IAMUser", + "principalId": "...", + "arn": "arn:aws:iam::123412341234:user/myuser", + "accountId": "123412341234", + "accessKeyId": "...", + "userName": "Alice" + }, + "protocolVersion": "1.00" +} diff --git a/packages/parser/tests/events/s3ObjectEventTempCredentials.json b/packages/parser/tests/events/s3ObjectEventTempCredentials.json new file mode 100644 index 0000000000..30c70fe6df --- /dev/null +++ b/packages/parser/tests/events/s3ObjectEventTempCredentials.json @@ -0,0 +1,42 @@ +{ + "xAmzRequestId": "requestId", + "getObjectContext": { + "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=", + "outputRoute": "io-use1-001", + "outputToken": "OutputToken" + }, + "configuration": { + "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", + "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", + "payload": "{}" + }, + "userRequest": { + "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", + "headers": { + "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", + "Accept-Encoding": "identity", + "X-Amz-Content-SHA256": "e3b0c44298fc1example" + } + }, + "userIdentity": { + "type": "AssumedRole", + "principalId": "principalId", + "arn": "arn:aws:sts::111122223333:assumed-role/Admin/example", + "accountId": "111122223333", + "accessKeyId": "accessKeyId", + "sessionContext": { + "attributes": { + "mfaAuthenticated": "false", + "creationDate": "Wed Mar 10 23:41:52 UTC 2021" + }, + "sessionIssuer": { + "type": "Role", + "principalId": "principalId", + "arn": "arn:aws:iam::111122223333:role/Admin", + "accountId": "111122223333", + "userName": "Admin" + } + } + }, + "protocolVersion": "1.00" +} diff --git a/packages/parser/tests/events/s3SqsEvent.json b/packages/parser/tests/events/s3SqsEvent.json new file mode 100644 index 0000000000..55863af12b --- /dev/null +++ b/packages/parser/tests/events/s3SqsEvent.json @@ -0,0 +1,22 @@ +{ + "Records":[ + { + "messageId":"ca3e7a89-c358-40e5-8aa0-5da01403c267", + "receiptHandle":"AQEBE7XoI7IQRLF7SrpiW9W4BanmOWe8UtVDbv6/CEZYKf/OktSNIb4j689tQfR4k44V/LY20lZ5VpxYt2GTYCsSLKTcBalTJaRX9CKu/hVqy/23sSNiKxnP56D+VLSn+hU275+AP1h4pUL0d9gLdRB2haX8xiM+LcGfis5Jl8BBXtoxKRF60O87O9/NvCmmXLeqkJuexfyEZNyed0fFCRXFXSjbmThG0OIQgcrGI8glBRGPA8htns58VtXFsSaPYNoqP3p5n6+ewKKVLD0lfm+0DlnLKRa+mjvFBaSer9KK1ff+Aq6zJ6HynPwADj+aF70Hwimc2zImYe51SLEF/E2csYlMNZYI/2qXW0m9R7wJ/XDTV4g2+h+BMTxsKnJQ6NQd", + "body":"{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventTime\":\"2023-04-12T20:43:38.021Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"requestParameters\":{\"sourceIPAddress\":\"93.108.161.96\"},\"responseElements\":{\"x-amz-request-id\":\"YMSSR8BZJ2Y99K6P\",\"x-amz-id-2\":\"6ASrUfj5xpn859fIq+6FXflOex/SKl/rjfiMd7wRzMg/zkHKR22PDpnh7KD3uq//cuOTbdX4DInN5eIs+cR0dY1z2Mc5NDP/\"},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"SNS\",\"bucket\":{\"name\":\"xxx\",\"ownerIdentity\":{\"principalId\":\"A1YQ72UWCM96UF\"},\"arn\":\"arn:aws:s3:::xxx\"},\"object\":{\"key\":\"test.pdf\",\"size\":104681,\"eTag\":\"2e3ad1e983318bbd8e73b080e2997980\",\"versionId\":\"yd3d4HaWOT2zguDLvIQLU6ptDTwKBnQV\",\"sequencer\":\"00643717F9F8B85354\"}}}]}", + "attributes":{ + "ApproximateReceiveCount":"1", + "SentTimestamp":"1681332219270", + "SenderId":"AIDAJHIPRHEMV73VRJEBU", + "ApproximateFirstReceiveTimestamp":"1681332239270" + }, + "messageAttributes":{ + + }, + "md5OfBody":"16f4460f4477d8d693a5abe94fdbbd73", + "eventSource":"aws:sqs", + "eventSourceARN":"arn:aws:sqs:us-east-1:123456789012:SQS", + "awsRegion":"us-east-1" + } + ] + } diff --git a/packages/parser/tests/events/secretsManagerEvent.json b/packages/parser/tests/events/secretsManagerEvent.json new file mode 100644 index 0000000000..f07ea1e0b0 --- /dev/null +++ b/packages/parser/tests/events/secretsManagerEvent.json @@ -0,0 +1,5 @@ +{ + "SecretId":"arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "ClientRequestToken":"550e8400-e29b-41d4-a716-446655440000", + "Step":"createSecret" +} \ No newline at end of file diff --git a/packages/parser/tests/events/sesEvent.json b/packages/parser/tests/events/sesEvent.json new file mode 100644 index 0000000000..636ecad687 --- /dev/null +++ b/packages/parser/tests/events/sesEvent.json @@ -0,0 +1,101 @@ +{ + "Records": [ + { + "eventVersion": "1.0", + "ses": { + "mail": { + "commonHeaders": { + "from": [ + "Jane Doe " + ], + "to": [ + "johndoe@example.com" + ], + "returnPath": "janedoe@example.com", + "messageId": "<0123456789example.com>", + "date": "Wed, 7 Oct 2015 12:34:56 -0700", + "subject": "Test Subject" + }, + "source": "janedoe@example.com", + "timestamp": "1970-01-01T00:00:00.000Z", + "destination": [ + "johndoe@example.com" + ], + "headers": [ + { + "name": "Return-Path", + "value": "" + }, + { + "name": "Received", + "value": "from mailer.example.com (mailer.example.com [203.0.113.1]) by ..." + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=example; ..." + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "From", + "value": "Jane Doe " + }, + { + "name": "Date", + "value": "Wed, 7 Oct 2015 12:34:56 -0700" + }, + { + "name": "Message-ID", + "value": "<0123456789example.com>" + }, + { + "name": "Subject", + "value": "Test Subject" + }, + { + "name": "To", + "value": "johndoe@example.com" + }, + { + "name": "Content-Type", + "value": "text/plain; charset=UTF-8" + } + ], + "headersTruncated": false, + "messageId": "o3vrnil0e2ic28tr" + }, + "receipt": { + "recipients": [ + "johndoe@example.com" + ], + "timestamp": "1970-01-01T00:00:00.000Z", + "spamVerdict": { + "status": "PASS" + }, + "dkimVerdict": { + "status": "PASS" + }, + "dmarcPolicy": "reject", + "processingTimeMillis": 574, + "action": { + "type": "Lambda", + "invocationType": "Event", + "functionArn": "arn:aws:lambda:us-west-2:012345678912:function:Example" + }, + "dmarcVerdict": { + "status": "PASS" + }, + "spfVerdict": { + "status": "PASS" + }, + "virusVerdict": { + "status": "PASS" + } + } + }, + "eventSource": "aws:ses" + } + ] +} diff --git a/packages/parser/tests/events/snsEvent.json b/packages/parser/tests/events/snsEvent.json new file mode 100644 index 0000000000..3d8a8ed443 --- /dev/null +++ b/packages/parser/tests/events/snsEvent.json @@ -0,0 +1,31 @@ +{ + "Records": [ + { + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:sns-la ...", + "EventSource": "aws:sns", + "Sns": { + "SignatureVersion": "1", + "Timestamp": "2019-01-02T12:45:07.000Z", + "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", + "SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotification", + "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", + "Message": "Hello from SNS!", + "MessageAttributes": { + "Test": { + "Type": "String", + "Value": "TestString" + }, + "TestBinary": { + "Type": "Binary", + "Value": "TestBinary" + } + }, + "Type": "Notification", + "UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe", + "TopicArn": "arn:aws:sns:us-east-2:123456789012:sns-lambda", + "Subject": "TestInvoke" + } + } + ] +} \ No newline at end of file diff --git a/packages/parser/tests/events/snsSqsEvent.json b/packages/parser/tests/events/snsSqsEvent.json new file mode 100644 index 0000000000..ee440fc296 --- /dev/null +++ b/packages/parser/tests/events/snsSqsEvent.json @@ -0,0 +1,20 @@ +{ + "Records": [ + { + "messageId": "79406a00-bf15-46ca-978c-22c3613fcb30", + "receiptHandle": "AQEB3fkqlBqq239bMCAHIr5mZkxJYKtxsTTy1lMImmpY7zqpQdfcAE8zFiuRh7X5ciROy24taT2rRXfuJFN/yEUVcQ6d5CIOCEK4htmRJJOHIyGdZPAm2NUUG5nNn2aEzgfzVvrkPBsrCbr7XTzK5s6eUZNH/Nn9AJtHKHpzweRK34Bon9OU/mvyIT7EJbwHPsdhL14NrCp8pLWBiIhkaJkG2G6gPO89dwHtGVUARJL+zP70AuIu/f7QgmPtY2eeE4AVbcUT1qaIlSGHUXxoHq/VMHLd/c4zWl0EXQOo/90DbyCUMejTIKL7N15YfkHoQDHprvMiAr9S75cdMiNOduiHzZLg/qVcv4kxsksKLFMKjwlzmYuQYy2KslVGwoHMd4PD", + "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"d88d4479-6ec0-54fe-b63f-1cf9df4bb16e\",\n \"TopicArn\" : \"arn:aws:sns:eu-west-1:231436140809:powertools265\",\n \"Message\" : \"{\\\"message\\\": \\\"hello world\\\", \\\"username\\\": \\\"lessa\\\"}\",\n \"Timestamp\" : \"2021-01-19T10:07:07.287Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"tEo2i6Lw6/Dr7Jdlulh0sXgnkF0idd3hqs8QZCorQpzkIWVOuu583NT0Gv0epuZD1Bo+tex6NgP5p6415yNVujGHJKnkrA9ztzXaVgFiol8rf8AFGQbmb7RsM9BqATQUJeg9nCTe0jksmWXmjxEFr8XKyyRuQBwSlRTngAvOw8jUnCe1vyYD5xPec1xpfOEGLi5BqSog+6tBtsry3oAtcENX8SV1tVuMpp6D+UrrU8xNT/5D70uRDppkPE3vq+t7rR0fVSdQRdUV9KmQD2bflA1Dyb2y37EzwJOMHDDQ82aOhj/JmPxvEAlV8RkZl6J0HIveraRy9wbNLbI7jpiOCw==\",\n \"SigningCertURL\" : \"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem\",\n \"UnsubscribeURL\" : \"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:231436140809:powertools265:15189ad7-870e-40e5-a7dd-a48898cd9f86\"\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1611050827340", + "SenderId": "AIDAISMY7JYY5F7RTT6AO", + "ApproximateFirstReceiveTimestamp": "1611050827344" + }, + "messageAttributes": {}, + "md5OfBody": "8910bdaaf9a30a607f7891037d4af0b0", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-west-1:231436140809:powertools265", + "awsRegion": "eu-west-1" + } + ] +} diff --git a/packages/parser/tests/events/snsSqsFifoEvent.json b/packages/parser/tests/events/snsSqsFifoEvent.json new file mode 100644 index 0000000000..6c23ef6294 --- /dev/null +++ b/packages/parser/tests/events/snsSqsFifoEvent.json @@ -0,0 +1,23 @@ +{ + "Records": [ + { + "messageId": "69bc4bbd-ed69-4325-a434-85c3b428ceab", + "receiptHandle": "AQEBbfAqjhrgIdW3HGWYPz57mdDatG/dT9LZhRPAsNQ1pJmw495w4esDc8ZSbOwMZuPBol7wtiNWug8U25GpSQDDLY1qv//8/lfmdzXOiprG6xRVeiXSHj0j731rJQ3xo+GPdGjOzjIxI09CrE3HtZ4lpXY9NjjHzP8hdxkCLlbttumc8hDBUR365/Tk+GfV2nNP9qvZtLGEbKCdTm/GYdTSoAr+ML9HnnGrS9T25Md71ASiZMI4DZqptN6g7CYYojFPs1LVM9o1258ferA72zbNoQ==", + "body": "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"a7c9d2fa-77fa-5184-9de9-89391027cc7d\",\n \"SequenceNumber\" : \"10000000000000004000\",\n \"TopicArn\" : \"arn:aws:sns:eu-west-1:231436140809:Test.fifo\",\n \"Message\" : \"{\\\"message\\\": \\\"hello world\\\", \\\"username\\\": \\\"lessa\\\"}\",\n \"Timestamp\" : \"2022-10-14T13:35:25.419Z\",\n \"UnsubscribeURL\" : \"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:231436140809:Test.fifo:bb81d3de-a0f9-46e4-b619-d3152a4d545f\"\n}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1665754525442", + "SequenceNumber": "18873177232222703872", + "MessageGroupId": "powertools-test", + "SenderId": "AIDAWYJAWPFU7SUQGUJC6", + "MessageDeduplicationId": "4e0a0f61eed277a4b9e4c01d5722b07b0725e42fe782102abee5711adfac701f", + "ApproximateFirstReceiveTimestamp": "1665754525442" + }, + "messageAttributes": {}, + "md5OfBody": "f3c788e623445e3feb263e80c1bffc0b", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:eu-west-1:231436140809:Test.fifo", + "awsRegion": "eu-west-1" + } + ] +} \ No newline at end of file diff --git a/packages/parser/tests/events/sqsEvent.json b/packages/parser/tests/events/sqsEvent.json new file mode 100644 index 0000000000..2bfcd1c7b8 --- /dev/null +++ b/packages/parser/tests/events/sqsEvent.json @@ -0,0 +1,42 @@ +{ + "Records": [ + { + "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", + "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", + "body": "Test message.", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1545082649183", + "SenderId": "AIDAIENQZJOLO23YVJ4VO", + "ApproximateFirstReceiveTimestamp": "1545082649185" + }, + "messageAttributes": { + "testAttr": { + "stringValue": "100", + "binaryValue": "base64Str", + "dataType": "Number" + } + }, + "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", + "awsRegion": "us-east-2" + }, + { + "messageId": "2e1424d4-f796-459a-8184-9c92662be6da", + "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", + "body": "{\"message\": \"foo1\"}", + "attributes": { + "ApproximateReceiveCount": "1", + "SentTimestamp": "1545082650636", + "SenderId": "AIDAIENQZJOLO23YVJ4VO", + "ApproximateFirstReceiveTimestamp": "1545082650649" + }, + "messageAttributes": {}, + "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", + "eventSource": "aws:sqs", + "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", + "awsRegion": "us-east-2" + } + ] +} diff --git a/packages/parser/tests/events/vpcLatticeEvent.json b/packages/parser/tests/events/vpcLatticeEvent.json new file mode 100644 index 0000000000..936bfb22d1 --- /dev/null +++ b/packages/parser/tests/events/vpcLatticeEvent.json @@ -0,0 +1,15 @@ +{ + "raw_path": "/testpath", + "method": "GET", + "headers": { + "user_agent": "curl/7.64.1", + "x-forwarded-for": "10.213.229.10", + "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + "accept": "*/*" + }, + "query_string_parameters": { + "order-id": "1" + }, + "body": "eyJ0ZXN0IjogImV2ZW50In0=", + "is_base64_encoded": true +} diff --git a/packages/parser/tests/events/vpcLatticeEventPathTrailingSlash.json b/packages/parser/tests/events/vpcLatticeEventPathTrailingSlash.json new file mode 100644 index 0000000000..7f6c0cfd9a --- /dev/null +++ b/packages/parser/tests/events/vpcLatticeEventPathTrailingSlash.json @@ -0,0 +1,15 @@ +{ + "raw_path": "/testpath/", + "method": "GET", + "headers": { + "user_agent": "curl/7.64.1", + "x-forwarded-for": "10.213.229.10", + "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + "accept": "*/*" + }, + "query_string_parameters": { + "order-id": "1" + }, + "body": "eyJ0ZXN0IjogImV2ZW50In0=", + "is_base64_encoded": true +} diff --git a/packages/parser/tests/events/vpcLatticeEventV2PathTrailingSlash.json b/packages/parser/tests/events/vpcLatticeEventV2PathTrailingSlash.json new file mode 100644 index 0000000000..a9f0188852 --- /dev/null +++ b/packages/parser/tests/events/vpcLatticeEventV2PathTrailingSlash.json @@ -0,0 +1,30 @@ +{ + "version": "2.0", + "path": "/newpath/", + "method": "GET", + "headers": { + "user_agent": "curl/7.64.1", + "x-forwarded-for": "10.213.229.10", + "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + "accept": "*/*" + }, + "queryStringParameters": { + "order-id": "1" + }, + "body": "{\"message\": \"Hello from Lambda!\"}", + "isBase64Encoded": false, + "requestContext": { + "serviceNetworkArn": "arn:aws:vpc-lattice:us-east-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a", + "serviceArn": "arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-0a40eebed65f8d69c", + "targetGroupArn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-6d0ecf831eec9f09", + "identity": { + "sourceVpcArn": "arn:aws:ec2:region:123456789012:vpc/vpc-0b8276c84697e7339", + "type" : "AWS_IAM", + "principal": "arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf", + "sessionName": "057d00f8b51257ba3c853a0f248943cf", + "x509SanDns": "example.com" + }, + "region": "us-east-2", + "timeEpoch": "1696331543569073" + } +} diff --git a/packages/parser/tests/events/vpcLatticeV2Event.json b/packages/parser/tests/events/vpcLatticeV2Event.json new file mode 100644 index 0000000000..fe10d83a3a --- /dev/null +++ b/packages/parser/tests/events/vpcLatticeV2Event.json @@ -0,0 +1,30 @@ +{ + "version": "2.0", + "path": "/newpath", + "method": "GET", + "headers": { + "user_agent": "curl/7.64.1", + "x-forwarded-for": "10.213.229.10", + "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + "accept": "*/*" + }, + "queryStringParameters": { + "order-id": "1" + }, + "body": "{\"message\": \"Hello from Lambda!\"}", + "isBase64Encoded": false, + "requestContext": { + "serviceNetworkArn": "arn:aws:vpc-lattice:us-east-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a", + "serviceArn": "arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-0a40eebed65f8d69c", + "targetGroupArn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-6d0ecf831eec9f09", + "identity": { + "sourceVpcArn": "arn:aws:ec2:region:123456789012:vpc/vpc-0b8276c84697e7339", + "type" : "AWS_IAM", + "principal": "arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf", + "sessionName": "057d00f8b51257ba3c853a0f248943cf", + "x509SanDns": "example.com" + }, + "region": "us-east-2", + "timeEpoch": "1696331543569073" + } +} diff --git a/packages/parser/tests/tsconfig.json b/packages/parser/tests/tsconfig.json new file mode 100644 index 0000000000..dc4ebdfc5f --- /dev/null +++ b/packages/parser/tests/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "../", + "noEmit": true + }, + "include": [ + "../src/**/*", + "./**/*.*" + ] +} \ No newline at end of file diff --git a/packages/parser/tests/unit/schema/alb.test.ts b/packages/parser/tests/unit/schema/alb.test.ts new file mode 100644 index 0000000000..5e9144582e --- /dev/null +++ b/packages/parser/tests/unit/schema/alb.test.ts @@ -0,0 +1,33 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ +import { + AlbSchema, + AlbMultiValueHeadersSchema, +} from '../../../src/schemas/alb.js'; +import { loadExampleEvent } from './utils.js'; + +describe('ALB ', () => { + it('should parse alb event', () => { + const albEvent = loadExampleEvent('albEvent.json'); + expect(AlbSchema.parse(albEvent)).toEqual(albEvent); + }); + it('should parse alb event path trailing slash', () => { + const albEventPathTrailingSlash = loadExampleEvent( + 'albEventPathTrailingSlash.json' + ); + expect(AlbSchema.parse(albEventPathTrailingSlash)).toEqual( + albEventPathTrailingSlash + ); + }); + it('should parse alb event with multi value headers event', () => { + const albMultiValueHeadersEvent = loadExampleEvent( + 'albMultiValueHeadersEvent.json' + ); + expect(AlbMultiValueHeadersSchema.parse(albMultiValueHeadersEvent)).toEqual( + albMultiValueHeadersEvent + ); + }); +}); diff --git a/packages/parser/tests/unit/schema/apigw.test.ts b/packages/parser/tests/unit/schema/apigw.test.ts new file mode 100644 index 0000000000..9aa23c6694 --- /dev/null +++ b/packages/parser/tests/unit/schema/apigw.test.ts @@ -0,0 +1,102 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { APIGatewayProxyEventSchema } from '../../../src/schemas/apigw.js'; + +describe('APIGateway ', () => { + it('should parse api gateway event', () => { + const apiGatewayProxyEvent = loadExampleEvent('apiGatewayProxyEvent.json'); + expect(APIGatewayProxyEventSchema.parse(apiGatewayProxyEvent)).toEqual( + apiGatewayProxyEvent + ); + }); + it('should parse api gateway authorizer request event', () => { + const apiGatewayAuthorizerRequestEvent = loadExampleEvent( + 'apiGatewayAuthorizerRequestEvent.json' + ); + expect( + APIGatewayProxyEventSchema.parse(apiGatewayAuthorizerRequestEvent) + ).toEqual(apiGatewayAuthorizerRequestEvent); + }); + it('should parse schema middleware invalid event', () => { + const apiGatewaySchemaMiddlewareInvalidEvent = loadExampleEvent( + 'apiGatewaySchemaMiddlewareInvalidEvent.json' + ); + expect( + APIGatewayProxyEventSchema.parse(apiGatewaySchemaMiddlewareInvalidEvent) + ).toEqual(apiGatewaySchemaMiddlewareInvalidEvent); + }); + it('should parse schema middleware valid event', () => { + const apiGatewaySchemaMiddlewareValidEvent = loadExampleEvent( + 'apiGatewaySchemaMiddlewareValidEvent.json' + ); + expect( + APIGatewayProxyEventSchema.parse(apiGatewaySchemaMiddlewareValidEvent) + ).toEqual(apiGatewaySchemaMiddlewareValidEvent); + }); + it('should parse proxy event with no version auth', () => { + const apiGatewayProxyEvent_noVersionAuth = loadExampleEvent( + 'apiGatewayProxyEvent_noVersionAuth.json' + ); + expect( + APIGatewayProxyEventSchema.parse(apiGatewayProxyEvent_noVersionAuth) + ).toEqual(apiGatewayProxyEvent_noVersionAuth); + }); + it('should parse proxy event with another path', () => { + const apiGatewayProxyEventAnotherPath = loadExampleEvent( + 'apiGatewayProxyEventAnotherPath.json' + ); + expect( + APIGatewayProxyEventSchema.parse(apiGatewayProxyEventAnotherPath) + ).toEqual(apiGatewayProxyEventAnotherPath); + }); + it('should parse proxy event with path trailing slash', () => { + const apiGatewayProxyEventPathTrailingSlash = loadExampleEvent( + 'apiGatewayProxyEventPathTrailingSlash.json' + ); + expect( + APIGatewayProxyEventSchema.parse(apiGatewayProxyEventPathTrailingSlash) + ).toEqual(apiGatewayProxyEventPathTrailingSlash); + }); + it('should parse other proxy event', () => { + const apiGatewayProxyOtherEvent = loadExampleEvent( + 'apiGatewayProxyOtherEvent.json' + ); + expect(APIGatewayProxyEventSchema.parse(apiGatewayProxyOtherEvent)).toEqual( + apiGatewayProxyOtherEvent + ); + }); + it('should throw error when event is not a valid proxy event', () => { + const event = { + resource: '/', + path: '/', + httpMethod: 'GET', + headers: {}, + multiValueHeaders: {}, + isBase64Encoded: false, + body: 'Foo!', + requestContext: { + accountId: '1234', + apiId: 'myApi', + httpMethod: 'GET', + identity: { + sourceIp: '127.0.0.1', + }, + path: '/', + protocol: 'Https', + requestId: '1234', + requestTime: '2018-09-07T16:20:46Z', + requestTimeEpoch: 1536992496000, + resourcePath: '/', + stage: 'test', + eventType: 'DISCONNECT', + messageId: 'messageId', + }, + }; + expect(() => APIGatewayProxyEventSchema.parse(event)).toThrow(); + }); +}); diff --git a/packages/parser/tests/unit/schema/apigwv2.test.ts b/packages/parser/tests/unit/schema/apigwv2.test.ts new file mode 100644 index 0000000000..85ac2da1a2 --- /dev/null +++ b/packages/parser/tests/unit/schema/apigwv2.test.ts @@ -0,0 +1,71 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { APIGatewayProxyEventV2Schema } from '../../../src/schemas/apigwv2.js'; + +describe('API GW v2 ', () => { + it('should parse api gateway v2 event', () => { + const apiGatewayProxyV2Event = loadExampleEvent( + 'apiGatewayProxyV2Event.json' + ); + expect(APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2Event)).toEqual( + apiGatewayProxyV2Event + ); + }); + it('should parse api gateway v2 event with GET method', () => { + const apiGatewayProxyV2Event_GET = loadExampleEvent( + 'apiGatewayProxyV2Event_GET.json' + ); + expect( + APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2Event_GET) + ).toEqual(apiGatewayProxyV2Event_GET); + }); + it('should parse api gateway v2 event with path trailing slash', () => { + const apiGatewayProxyV2EventPathTrailingSlash = loadExampleEvent( + 'apiGatewayProxyV2EventPathTrailingSlash.json' + ); + expect( + APIGatewayProxyEventV2Schema.parse( + apiGatewayProxyV2EventPathTrailingSlash + ) + ).toEqual(apiGatewayProxyV2EventPathTrailingSlash); + }); + it('should parse api gateway v2 event with iam', () => { + const apiGatewayProxyV2IamEvent = loadExampleEvent( + 'apiGatewayProxyV2IamEvent.json' + ); + expect( + APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2IamEvent) + ).toEqual(apiGatewayProxyV2IamEvent); + }); + it('should parse api gateway v2 event with lambda authorizer', () => { + const apiGatewayProxyV2LambdaAuthorizerEvent = loadExampleEvent( + 'apiGatewayProxyV2LambdaAuthorizerEvent.json' + ); + expect( + APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2LambdaAuthorizerEvent) + ).toEqual(apiGatewayProxyV2LambdaAuthorizerEvent); + }); + it('should parse api gateway v2 event with other get event', () => { + const apiGatewayProxyV2OtherGetEvent = loadExampleEvent( + 'apiGatewayProxyV2OtherGetEvent.json' + ); + expect( + APIGatewayProxyEventV2Schema.parse(apiGatewayProxyV2OtherGetEvent) + ).toEqual(apiGatewayProxyV2OtherGetEvent); + }); + it('should parse api gateway v2 event with schema middleware', () => { + const apiGatewayProxyV2SchemaMiddlewareValidEvent = loadExampleEvent( + 'apiGatewayProxyV2SchemaMiddlewareValidEvent.json' + ); + expect( + APIGatewayProxyEventV2Schema.parse( + apiGatewayProxyV2SchemaMiddlewareValidEvent + ) + ).toEqual(apiGatewayProxyV2SchemaMiddlewareValidEvent); + }); +}); diff --git a/packages/parser/tests/unit/schema/cloudformation-custom-resource.test.ts b/packages/parser/tests/unit/schema/cloudformation-custom-resource.test.ts new file mode 100644 index 0000000000..66ec61680d --- /dev/null +++ b/packages/parser/tests/unit/schema/cloudformation-custom-resource.test.ts @@ -0,0 +1,45 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { + CloudFormationCustomResourceCreateSchema, + CloudFormationCustomResourceUpdateSchema, + CloudFormationCustomResourceDeleteSchema, +} from '../../../src/schemas/cloudformation-custom-resource.js'; + +describe('CloudFormationCustomResource ', () => { + it('should parse create event', () => { + const cloudFormationCustomResourceCreateEvent = loadExampleEvent( + 'cloudFormationCustomResourceCreateEvent.json' + ); + expect( + CloudFormationCustomResourceCreateSchema.parse( + cloudFormationCustomResourceCreateEvent + ) + ).toEqual(cloudFormationCustomResourceCreateEvent); + }); + it('should parse update event', () => { + const cloudFormationCustomResourceUpdateEvent = loadExampleEvent( + 'cloudFormationCustomResourceUpdateEvent.json' + ); + expect( + CloudFormationCustomResourceUpdateSchema.parse( + cloudFormationCustomResourceUpdateEvent + ) + ).toEqual(cloudFormationCustomResourceUpdateEvent); + }); + it('should parse delete event', () => { + const cloudFormationCustomResourceDeleteEvent = loadExampleEvent( + 'cloudFormationCustomResourceDeleteEvent.json' + ); + expect( + CloudFormationCustomResourceDeleteSchema.parse( + cloudFormationCustomResourceDeleteEvent + ) + ).toEqual(cloudFormationCustomResourceDeleteEvent); + }); +}); diff --git a/packages/parser/tests/unit/schema/cloudwatch.test.ts b/packages/parser/tests/unit/schema/cloudwatch.test.ts new file mode 100644 index 0000000000..a978030de2 --- /dev/null +++ b/packages/parser/tests/unit/schema/cloudwatch.test.ts @@ -0,0 +1,30 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { CloudWatchLogsSchema } from '../../../src/schemas/cloudwatch.js'; + +describe('CloudWatchLogs ', () => { + it('should parse cloudwatch logs event', () => { + const cloudWatchLogEvent = loadExampleEvent('cloudWatchLogEvent.json'); + const parsed = CloudWatchLogsSchema.parse(cloudWatchLogEvent); + expect(parsed.awslogs.data).toBeDefined(); + expect(parsed.awslogs.data?.logEvents[0]).toEqual({ + id: 'eventId1', + timestamp: 1440442987000, + message: '[ERROR] First test message', + }); + }); + it('should throw error if cloudwatch logs event is invalid', () => { + expect(() => + CloudWatchLogsSchema.parse({ + awslogs: { + data: 'invalid', + }, + }) + ).toThrowError(); + }); +}); diff --git a/packages/parser/tests/unit/schema/dynamodb.test.ts b/packages/parser/tests/unit/schema/dynamodb.test.ts new file mode 100644 index 0000000000..b152c07b72 --- /dev/null +++ b/packages/parser/tests/unit/schema/dynamodb.test.ts @@ -0,0 +1,17 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { DynamoDBStreamSchema } from '../../../src/schemas/dynamodb.js'; +import { loadExampleEvent } from './utils.js'; + +describe('DynamoDB ', () => { + const dynamoStreamEvent = loadExampleEvent('dynamoStreamEvent.json'); + it('should parse a stream of records', () => { + expect(DynamoDBStreamSchema.parse(dynamoStreamEvent)).toEqual( + dynamoStreamEvent + ); + }); +}); diff --git a/packages/parser/tests/unit/schema/eventbridge.test.ts b/packages/parser/tests/unit/schema/eventbridge.test.ts new file mode 100644 index 0000000000..e92bd2248f --- /dev/null +++ b/packages/parser/tests/unit/schema/eventbridge.test.ts @@ -0,0 +1,15 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { EventBridgeSchema } from '../../../src/schemas/eventbridge.js'; + +describe('EventBridge ', () => { + it('should parse eventbridge event', () => { + const eventBridgeEvent = loadExampleEvent('eventBridgeEvent.json'); + expect(EventBridgeSchema.parse(eventBridgeEvent)).toEqual(eventBridgeEvent); + }); +}); diff --git a/packages/parser/tests/unit/schema/kafka.test.ts b/packages/parser/tests/unit/schema/kafka.test.ts new file mode 100644 index 0000000000..3b2bc50b83 --- /dev/null +++ b/packages/parser/tests/unit/schema/kafka.test.ts @@ -0,0 +1,63 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { + KafkaMskEventSchema, + KafkaSelfManagedEventSchema, +} from '../../../src/schemas/kafka.js'; + +describe('Kafka ', () => { + const expectedTestEvent = { + key: 'recordKey', + value: JSON.stringify({ key: 'value' }), + partition: 0, + topic: 'mytopic', + offset: 15, + timestamp: 1545084650987, + timestampType: 'CREATE_TIME', + headers: [ + { + headerKey: 'headerValue', + }, + ], + }; + it('should parse kafka MSK event', () => { + const kafkaEventMsk = loadExampleEvent('kafkaEventMsk.json'); + expect( + KafkaMskEventSchema.parse(kafkaEventMsk).records['mytopic-0'][0] + ).toEqual(expectedTestEvent); + }); + it('should parse kafka self managed event', () => { + const kafkaEventSelfManaged = loadExampleEvent( + 'kafkaEventSelfManaged.json' + ); + expect( + KafkaSelfManagedEventSchema.parse(kafkaEventSelfManaged).records[ + 'mytopic-0' + ][0] + ).toEqual(expectedTestEvent); + }); + it('should transform bootstrapServers to array', () => { + const kafkaEventSelfManaged = loadExampleEvent( + 'kafkaEventSelfManaged.json' + ); + expect( + KafkaSelfManagedEventSchema.parse(kafkaEventSelfManaged).bootstrapServers + ).toEqual([ + 'b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092', + 'b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092', + ]); + }); + it('should return undefined if bootstrapServers is not present', () => { + const kafkaEventSelfManaged = loadExampleEvent( + 'kafkaEventSelfManaged.json' + ) as { bootstrapServers: string }; + kafkaEventSelfManaged.bootstrapServers = ''; + const parsed = KafkaSelfManagedEventSchema.parse(kafkaEventSelfManaged); + expect(parsed.bootstrapServers).toBeUndefined(); + }); +}); diff --git a/packages/parser/tests/unit/schema/kinesis.test.ts b/packages/parser/tests/unit/schema/kinesis.test.ts new file mode 100644 index 0000000000..99fc5eebc4 --- /dev/null +++ b/packages/parser/tests/unit/schema/kinesis.test.ts @@ -0,0 +1,90 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { KinesisDataStreamSchema } from '../../../src/schemas/kinesis.js'; +import { + KinesisFirehoseSchema, + KinesisFirehoseSqsSchema, +} from '../../../src/schemas/kinesis-firehose.js'; +import { extractCloudWatchLogFromEvent } from '../../../src/schemas/cloudwatch.js'; + +describe('Kinesis ', () => { + it('should parse kinesis event', () => { + const kinesisStreamEvent = loadExampleEvent('kinesisStreamEvent.json'); + const parsed = KinesisDataStreamSchema.parse(kinesisStreamEvent); + const decodedData = Buffer.from( + parsed.Records[0].kinesis.data, + 'base64' + ).toString('utf8'); + expect(decodedData).toEqual('Hello, this is a test.'); + }); + it('should parse single kinesis record', () => { + const kinesisStreamEventOneRecord = loadExampleEvent( + 'kinesisStreamEventOneRecord.json' + ); + const parsed = KinesisDataStreamSchema.parse(kinesisStreamEventOneRecord); + const decodedJson = JSON.parse( + Buffer.from(parsed.Records[0].kinesis.data, 'base64').toString('utf8') + ); + expect(decodedJson).toEqual({ + message: 'test message', + username: 'test', + }); + }); + it('should parse Firehose event', () => { + const kinesisFirehoseKinesisEvent = loadExampleEvent( + 'kinesisFirehoseKinesisEvent.json' + ); + const parsed = KinesisFirehoseSchema.parse(kinesisFirehoseKinesisEvent); + expect(parsed.records[0].data).toEqual('Hello World'); + }); + it('should parse Kinesis Firehose PutEvents event', () => { + const kinesisFirehosePutEvent = loadExampleEvent( + 'kinesisFirehosePutEvent.json' + ); + const parsed = KinesisFirehoseSchema.parse(kinesisFirehosePutEvent); + expect(JSON.parse(parsed.records[1].data)).toEqual({ + Hello: 'World', + }); + }); + it('should parse Firehose event with SQS event', () => { + const kinesisFirehoseSQSEvent = loadExampleEvent( + 'kinesisFirehoseSQSEvent.json' + ); + const parsed = KinesisFirehoseSqsSchema.parse(kinesisFirehoseSQSEvent); + expect(parsed.records[0].data).toMatchObject({ + messageId: '5ab807d4-5644-4c55-97a3-47396635ac74', + body: 'Test message.', + }); + }); + it('should parse Firehose event with CloudWatch event', () => { + const kinesisStreamCloudWatchLogsEvent = loadExampleEvent( + 'kinesisStreamCloudWatchLogsEvent.json' + ); + const parsed = KinesisDataStreamSchema.parse( + kinesisStreamCloudWatchLogsEvent + ); + + const jsonParsed = extractCloudWatchLogFromEvent( + parsed.Records[0].kinesis.data + ); + expect(jsonParsed).toMatchObject({ + messageType: 'DATA_MESSAGE', + owner: '231436140809', + logGroup: '/aws/lambda/pt-1488-DummyLogDataFunction-gnWXPvL6jJyG', + logStream: '2022/11/10/[$LATEST]26b6a45d574f442ea28438923cbf7bf7', + }); + }); + it('should return original value if cannot parse KinesisFirehoseSqsRecord', () => { + const kinesisFirehoseSQSEvent = loadExampleEvent( + 'kinesisFirehoseSQSEvent.json' + ) as { records: { data: string }[] }; + kinesisFirehoseSQSEvent.records[0].data = 'not a valid json'; + const parsed = KinesisFirehoseSqsSchema.parse(kinesisFirehoseSQSEvent); + expect(parsed.records[0].data).toEqual('not a valid json'); + }); +}); diff --git a/packages/parser/tests/unit/schema/lambda.test.ts b/packages/parser/tests/unit/schema/lambda.test.ts new file mode 100644 index 0000000000..459cd8a32e --- /dev/null +++ b/packages/parser/tests/unit/schema/lambda.test.ts @@ -0,0 +1,19 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { LambdaFunctionUrlSchema } from '../../../src/schemas/lambda.js'; + +describe('Lambda ', () => { + it('should parse lambda event', () => { + const lambdaFunctionUrlEvent = loadExampleEvent( + 'apiGatewayProxyV2Event.json' + ); + expect(LambdaFunctionUrlSchema.parse(lambdaFunctionUrlEvent)).toEqual( + lambdaFunctionUrlEvent + ); + }); +}); diff --git a/packages/parser/tests/unit/schema/s3.test.ts b/packages/parser/tests/unit/schema/s3.test.ts new file mode 100644 index 0000000000..2c5378fdf7 --- /dev/null +++ b/packages/parser/tests/unit/schema/s3.test.ts @@ -0,0 +1,105 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { + S3EventNotificationEventBridgeSchema, + S3SqsEventNotificationSchema, + S3Schema, + S3ObjectLambdaEventSchema, +} from '../../../src/schemas/s3.js'; +import { loadExampleEvent } from './utils.js'; + +describe('S3 ', () => { + it('should parse s3 event', () => { + const s3Event = loadExampleEvent('s3Event.json'); + expect(S3Schema.parse(s3Event)).toEqual(s3Event); + }); + + it('should parse s3 event bridge notification event created', () => { + const s3EventBridgeNotificationObjectCreatedEvent = loadExampleEvent( + 's3EventBridgeNotificationObjectCreatedEvent.json' + ); + expect( + S3EventNotificationEventBridgeSchema.parse( + s3EventBridgeNotificationObjectCreatedEvent + ) + ).toEqual(s3EventBridgeNotificationObjectCreatedEvent); + }); + + it('should parse s3 event bridge notification event detelted', () => { + const s3EventBridgeNotificationObjectDeletedEvent = loadExampleEvent( + 's3EventBridgeNotificationObjectDeletedEvent.json' + ); + expect( + S3EventNotificationEventBridgeSchema.parse( + s3EventBridgeNotificationObjectDeletedEvent + ) + ).toEqual(s3EventBridgeNotificationObjectDeletedEvent); + }); + it('should parse s3 event bridge notification event expired', () => { + const s3EventBridgeNotificationObjectExpiredEvent = loadExampleEvent( + 's3EventBridgeNotificationObjectExpiredEvent.json' + ); + expect( + S3EventNotificationEventBridgeSchema.parse( + s3EventBridgeNotificationObjectExpiredEvent + ) + ).toEqual(s3EventBridgeNotificationObjectExpiredEvent); + }); + + it('should parse s3 sqs notification event', () => { + const s3SqsEvent = loadExampleEvent('s3SqsEvent.json'); + expect(S3SqsEventNotificationSchema.parse(s3SqsEvent)).toEqual(s3SqsEvent); + }); + + it('should parse s3 event with decoded key', () => { + const s3EventDecodedKey = loadExampleEvent('s3EventDecodedKey.json'); + expect(S3Schema.parse(s3EventDecodedKey)).toEqual(s3EventDecodedKey); + }); + + it('should parse s3 event delete object', () => { + const s3EventDeleteObject = loadExampleEvent('s3EventDeleteObject.json'); + expect(S3Schema.parse(s3EventDeleteObject)).toEqual(s3EventDeleteObject); + }); + + it('should parse s3 event glacier', () => { + const s3EventGlacier = loadExampleEvent('s3EventGlacier.json'); + expect(S3Schema.parse(s3EventGlacier)).toEqual(s3EventGlacier); + }); + + it('should parse s3 object event iam user', () => { + const s3ObjectEventIAMUser = loadExampleEvent('s3ObjectEventIAMUser.json'); + expect(S3ObjectLambdaEventSchema.parse(s3ObjectEventIAMUser)).toEqual( + s3ObjectEventIAMUser + ); + }); + + it('should parse s3 object event temp credentials', () => { + // ignore any because we don't want typed json + const s3ObjectEventTempCredentials = loadExampleEvent( + 's3ObjectEventTempCredentials.json' + ) as any; // eslint-disable-line @typescript-eslint/no-explicit-any + const parsed = S3ObjectLambdaEventSchema.parse( + s3ObjectEventTempCredentials + ); + + expect(parsed.userRequest).toEqual( + s3ObjectEventTempCredentials.userRequest + ); + expect(parsed.getObjectContext).toEqual( + s3ObjectEventTempCredentials.getObjectContext + ); + expect(parsed.configuration).toEqual( + s3ObjectEventTempCredentials.configuration + ); + expect(parsed.userRequest).toEqual( + s3ObjectEventTempCredentials.userRequest + ); + expect( + parsed.userIdentity?.sessionContext?.attributes.mfaAuthenticated + ).toEqual(false); + }); +}); diff --git a/packages/parser/tests/unit/schema/ses.test.ts b/packages/parser/tests/unit/schema/ses.test.ts new file mode 100644 index 0000000000..eeb29f6a1b --- /dev/null +++ b/packages/parser/tests/unit/schema/ses.test.ts @@ -0,0 +1,15 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { SesSchema } from '../../../src/schemas/ses.js'; + +describe('Schema:', () => { + const sesEvent = loadExampleEvent('sesEvent.json'); + it('SES should parse ses event', () => { + expect(SesSchema.parse(sesEvent)).toEqual(sesEvent); + }); +}); diff --git a/packages/parser/tests/unit/schema/sns.test.ts b/packages/parser/tests/unit/schema/sns.test.ts new file mode 100644 index 0000000000..66ec7aa297 --- /dev/null +++ b/packages/parser/tests/unit/schema/sns.test.ts @@ -0,0 +1,15 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { SnsSchema } from '../../../src/schemas/sns.js'; + +describe('Schema:', () => { + const snsEvent = loadExampleEvent('snsEvent.json'); + it('SNS should parse sns event', () => { + expect(SnsSchema.parse(snsEvent)).toEqual(snsEvent); + }); +}); diff --git a/packages/parser/tests/unit/schema/sqs.test.ts b/packages/parser/tests/unit/schema/sqs.test.ts new file mode 100644 index 0000000000..191b843298 --- /dev/null +++ b/packages/parser/tests/unit/schema/sqs.test.ts @@ -0,0 +1,15 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { SqsSchema } from '../../../src/schemas/sqs.js'; + +describe('SQS ', () => { + const sqsEvent = loadExampleEvent('sqsEvent.json'); + it('should parse sqs event', () => { + expect(SqsSchema.parse(sqsEvent)).toEqual(sqsEvent); + }); +}); diff --git a/packages/parser/tests/unit/schema/utils.ts b/packages/parser/tests/unit/schema/utils.ts new file mode 100644 index 0000000000..8101dfefdb --- /dev/null +++ b/packages/parser/tests/unit/schema/utils.ts @@ -0,0 +1,7 @@ +import { readFileSync } from 'node:fs'; + +export const loadExampleEvent = (fileName: string): unknown => { + const event = readFileSync(`./tests/events/${fileName}`, 'utf8'); + + return JSON.parse(event); +}; diff --git a/packages/parser/tests/unit/schema/vpc-lattice.test.ts b/packages/parser/tests/unit/schema/vpc-lattice.test.ts new file mode 100644 index 0000000000..ea0a0dd4a4 --- /dev/null +++ b/packages/parser/tests/unit/schema/vpc-lattice.test.ts @@ -0,0 +1,23 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { VpcLatticeSchema } from '../../../src/schemas/vpc-lattice.js'; + +describe('VPC Lattice ', () => { + it('should parse vpc lattice event', () => { + const vpcLatticeEvent = loadExampleEvent('vpcLatticeEvent.json'); + expect(VpcLatticeSchema.parse(vpcLatticeEvent)).toEqual(vpcLatticeEvent); + }); + it('should parse vpc lattice path trailing slash event', () => { + const vpcLatticeEventPathTrailingSlash = loadExampleEvent( + 'vpcLatticeEventPathTrailingSlash.json' + ); + expect(VpcLatticeSchema.parse(vpcLatticeEventPathTrailingSlash)).toEqual( + vpcLatticeEventPathTrailingSlash + ); + }); +}); diff --git a/packages/parser/tests/unit/schema/vpc-latticev2.test.ts b/packages/parser/tests/unit/schema/vpc-latticev2.test.ts new file mode 100644 index 0000000000..da6d7d885e --- /dev/null +++ b/packages/parser/tests/unit/schema/vpc-latticev2.test.ts @@ -0,0 +1,24 @@ +/** + * Test built in schema + * + * @group unit/parser/schema/ + */ + +import { loadExampleEvent } from './utils.js'; +import { VpcLatticeV2Schema } from '../../../src/schemas/vpc-latticev2.js'; + +describe('VpcLatticeV2 ', () => { + it('should parse VpcLatticeV2 event', () => { + const vpcLatticeV2Event = loadExampleEvent('vpcLatticeV2Event.json'); + const parsed = VpcLatticeV2Schema.parse(vpcLatticeV2Event); + expect(parsed).toEqual(vpcLatticeV2Event); + }); + + it('should parse VpcLatticeV2PathTrailingSlash event', () => { + const vpcLatticeEventV2PathTrailingSlash = loadExampleEvent( + 'vpcLatticeEventV2PathTrailingSlash.json' + ); + const parsed = VpcLatticeV2Schema.parse(vpcLatticeEventV2PathTrailingSlash); + expect(parsed).toEqual(vpcLatticeEventV2PathTrailingSlash); + }); +}); diff --git a/packages/parser/tsconfig.esm.json b/packages/parser/tsconfig.esm.json new file mode 100644 index 0000000000..123291b0cf --- /dev/null +++ b/packages/parser/tsconfig.esm.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.esm.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "./lib/esm", + "rootDir": "./src", + "tsBuildInfoFile": ".tsbuildinfo/esm.json" + }, + "include": [ + "./src/**/*" + ] +} \ No newline at end of file diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json index a62acd2a00..92aecd7c98 100644 --- a/packages/parser/tsconfig.json +++ b/packages/parser/tsconfig.json @@ -1,8 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./lib", + "outDir": "./lib/cjs/", "rootDir": "./src", + "tsBuildInfoFile": ".tsbuildinfo/cjs.json" }, "include": [ "./src/**/*" diff --git a/tsconfig.json b/tsconfig.json index 08d5af9848..0042e92513 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -44,5 +44,8 @@ { "path": "./packages/testing" }, + { + "path": "./packages/parser" + } ] } \ No newline at end of file