diff --git a/serverless/src/functions/apps/handler.ts b/serverless/src/functions/apps/handler.ts index b2e750d..dd99ca1 100644 --- a/serverless/src/functions/apps/handler.ts +++ b/serverless/src/functions/apps/handler.ts @@ -9,6 +9,24 @@ import { CreatePullZoneMethodArgs, LoadFreeCertificateMethodArgs, } from '@libs/bunnyCDN'; +import * as crypto from "crypto"; + +function isTheSignatureValid( + body: string, // must be raw string body, not json transformed version of the body + signature: string, // the "lambda-signature" from header + signingKey: string, // signing secret key for front-end +) { + const hmac = crypto.createHmac("sha256", signingKey); // Create a HMAC SHA256 hash using the signing key + hmac.update(body, "utf8"); // Update the token hash with the request body using utf8 + const digest = hmac.digest("hex"); + if (signature !== digest) { + // the request is not valid + return formatJSONResponse({ + status: 401, + message: 'Unauthorized', + }); + } +} export const verifyApp = async ( event: APIGatewayEvent @@ -23,6 +41,13 @@ export const verifyApp = async ( }); } + // Check the lambda-signature and confirm the value of the FE_SIGNING_KEY env variable. + // If both are valid, verify the authenticity of the request. + if (event.headers["lambda-signature"] === undefined) throw Error("Header field 'lambda-signature' was not found."); + + if (process.env.FE_SIGNING_KEY === undefined) throw Error("FE_SIGNING_KEY env variable not found."); + else { isTheSignatureValid(event.body, event.headers["lambda-signature"], process.env.FE_SIGNING_KEY); }; + // Set up constants const bunnyCdn = new BunnyCdn(process.env.BUNNY_CDN_ACCESS_KEY); const hostname = JSON.parse(event.body).hostname; @@ -50,13 +75,20 @@ export const submitAppInfo = async ( try { // Check the parameters and environment variables dotenv.config(); - if (event.body === null || process.env.BUNNY_CDN_ACCESS_KEY == undefined) { + if (event.body === null || process.env.BUNNY_CDN_ACCESS_KEY == undefined || event.headers.originUrl === undefined) { return formatJSONResponse({ status: 422, message: 'Required parameters were not passed.', }); } + // Check the lambda-signature and confirm the value of the FE_SIGNING_KEY env variable. + // If both are valid, verify the authenticity of the request. + if (event.headers["lambda-signature"] === undefined) throw Error("Header field 'lambda-signature' was not found."); + + if (process.env.FE_SIGNING_KEY === undefined) throw Error("FE_SIGNING_KEY env variable not found."); + else { isTheSignatureValid(event.body, event.headers["lambda-signature"], process.env.FE_SIGNING_KEY); }; + // Set up constants const bunnyCdn = new BunnyCdn(process.env.BUNNY_CDN_ACCESS_KEY); const data = JSON.parse(event.body); diff --git a/serverless/src/functions/builds/handler.ts b/serverless/src/functions/builds/handler.ts index b72b328..1156e39 100644 --- a/serverless/src/functions/builds/handler.ts +++ b/serverless/src/functions/builds/handler.ts @@ -27,7 +27,6 @@ export const submitBuildInfo = async ( domain: data.domain, verificationTransactionHash: 'Not verified.', }; - console.log(buildInfo); // Add build record to the database, if it's not already added const buildRecord = await prisma.builds.findMany({ @@ -38,11 +37,9 @@ export const submitBuildInfo = async ( domain: buildInfo.domain, }, }); - console.log(buildRecord); if (buildRecord.length == 0) { - console.log('here i am'); await prisma.builds.create({ data: { diff --git a/serverless/src/functions/mints/handler.ts b/serverless/src/functions/mints/handler.ts index 4a84524..3cf4d17 100644 --- a/serverless/src/functions/mints/handler.ts +++ b/serverless/src/functions/mints/handler.ts @@ -7,6 +7,25 @@ import { formatJSONResponse } from '@libs/api-gateway'; import { v4 } from 'uuid'; import { initPrisma, prisma } from '@libs/prisma'; import { contractInstance, web3 } from '@libs/nfa-contract'; +import * as crypto from "crypto"; + +function isTheSignatureValid( + body: string, // must be raw string body, not json transformed version of the body + signature: string, // the "x-alchemy-signature" from header + signingKey: string, // taken from dashboard for specific webhook +) { + const hmac = crypto.createHmac("sha256", signingKey); // Create a HMAC SHA256 hash using the signing key + hmac.update(body, "utf8"); // Update the token hash with the request body using utf8 + const digest = hmac.digest("hex"); + if (signature !== digest) { + // the request is not valid + return formatJSONResponse({ + status: 401, + message: 'Unauthorized', + }); + } +} + export const submitMintInfo = async ( event: APIGatewayEvent ///context: APIGatewayEventRequestContext @@ -18,12 +37,16 @@ export const submitMintInfo = async ( message: 'Required parameters were not passed.', }); } + + // Check the alchemy signature and confirm the value of the ALCHEMY_SIGNING_KEY env variable. + // If both are valid, verify the authenticity of the request. + if (event.headers["x-alchemy-signature"] === undefined) throw Error("Header field 'x-alchemy-signature' was not found."); + if (process.env.ALCHEMY_SIGNING_KEY === undefined) throw Error("ALCHEMY_SIGNING_KEY env variable not found."); + else { isTheSignatureValid(event.body, event.headers["x-alchemy-signature"], process.env.ALCHEMY_SIGNING_KEY); }; + const id = v4(); - /**if (!verifyAlchemySig(event.headers.xalchemywork)) { - throw new Error('Invalid sig'); - }**/ - + const eventBody = JSON.parse(event.body); const topics = eventBody.event.data.block.logs[1].topics.slice(1, 4); const hexCalldata = eventBody.event.data.block.logs[1].data; @@ -129,9 +152,9 @@ export const submitMintInfo = async ( domain: decodedLogs.externalURL, verificationTransactionHash: 'Not verified' }; - + initPrisma(); - + // Check if there is any build associated with the repository, commit hash, tokenId, and ipfsHash const build = await prisma.builds.findMany({