Skip to content

Commit

Permalink
feat: add receipts endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
vasco-santos committed Nov 13, 2023
1 parent 512223a commit d9f8591
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 2 deletions.
3 changes: 3 additions & 0 deletions stacks/ucan-invocation-stack.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export function UcanInvocationStack({ stack, app }) {
bucket: getBucketConfig('workflow-store', app.stage)
}
})
// Without arguments, this method will grant read ("s3:GetObject") access to all objects ("*") in the bucket.
workflowBucket.cdk.bucket.grantPublicAccess()

const invocationBucket = new Bucket(stack, 'invocation-store', {
cors: true,
cdk: {
Expand Down
1 change: 1 addition & 0 deletions stacks/upload-api-stack.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export function UploadApiStack({ stack, app }) {
'GET /error': 'functions/get.error',
'GET /version': 'functions/get.version',
'GET /metrics': 'functions/metrics.handler',
'GET /receipt/{taskCid}': 'functions/receipt.handler',
'GET /storefront-cron': 'functions/storefront-cron.handler',
// AWS API Gateway does not know trailing slash... and Grafana Agent puts trailing slash
'GET /metrics/{proxy+}': 'functions/metrics.handler',
Expand Down
4 changes: 2 additions & 2 deletions upload-api/buckets/invocation-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ export const useInvocationStore = (s3client, bucketName) => {
})
const listObject = await s3client.send(listObjectCmd)
const carEntry = listObject.Contents?.find(
content => content.Key?.endsWith('.workflow')
content => content.Key?.endsWith('.out')
)
if (!carEntry) {
return
}
return carEntry.Key?.replace(prefix, '').replace('.workflow', '')
return carEntry.Key?.replace(prefix, '').replace('.out', '')
}
}
}
57 changes: 57 additions & 0 deletions upload-api/functions/receipt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as Sentry from '@sentry/serverless'
import { parseLink } from '@ucanto/server'

import { createInvocationStore } from '../buckets/invocation-store.js'
import { mustGetEnv } from './utils.js'

Sentry.AWSLambda.init({
environment: process.env.SST_STAGE,
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
})

const AWS_REGION = process.env.AWS_REGION || 'us-west-2'

/**
* AWS HTTP Gateway handler for GET /receipt.
*
* @param {import('aws-lambda').APIGatewayProxyEventV2} event
*/
export async function receiptGet (event) {
const {
invocationBucketName,
workflowBucketName,
} = getLambdaEnv()
const invocationBucket = createInvocationStore(
AWS_REGION,
invocationBucketName
)

if (!event.pathParameters?.taskCid) {
return {
statusCode: 400,
body: Buffer.from(`no task cid received`).toString('base64'),
}
}
const taskCid = parseLink(event.pathParameters.taskCid)

const workflowLinkWithReceipt = await invocationBucket.getWorkflowLink(taskCid.toString())
const url = `https://${workflowBucketName}.s3.${AWS_REGION}.amazonaws.com/${workflowLinkWithReceipt}/${workflowLinkWithReceipt}`

// redirect to bucket
return {
statusCode: 302,
headers: {
Location: url
}
}
}

function getLambdaEnv () {
return {
invocationBucketName: mustGetEnv('INVOCATION_BUCKET_NAME'),
workflowBucketName: mustGetEnv('WORKFLOW_BUCKET_NAME'),
}
}

export const handler = Sentry.AWSLambda.wrapHandler(receiptGet)
3 changes: 3 additions & 0 deletions upload-api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { CID } from 'multiformats/cid'
import { Kinesis } from '@aws-sdk/client-kinesis'
import { AccountDID, ProviderDID, Service, SpaceDID } from '@web3-storage/upload-api'

export interface StoreOperationError extends Error {
name: 'StoreOperationFailed'
}

export interface UcanLogCtx extends WorkflowCtx, ReceiptBlockCtx {
basicAuth: string
Expand Down

0 comments on commit d9f8591

Please sign in to comment.