Skip to content

Commit e3728a4

Browse files
authored
Merge pull request #1 from agnostack/feat/initial
Initial commit
2 parents 95c9c3b + a24f971 commit e3728a4

File tree

9 files changed

+6168
-25
lines changed

9 files changed

+6168
-25
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
INTEGRATION_PUBLIC_KEY=
2+
BASE_API_PATH=

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Dependency directories
9+
node_modules/
10+
11+
# Optional npm cache directory
12+
.npm
13+
14+
# Yarn Integrity file
15+
.yarn-integrity
16+
17+
# misc
18+
package-lock.json
19+
.DS_Store
20+
.env
21+
.serverless
22+
23+
# local dev debugging
24+
.debug

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
18.20

LICENSE

Lines changed: 0 additions & 24 deletions
This file was deleted.

README.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,53 @@
1-
# secure-api-proxy
1+
# Secure API Proxy
2+
3+
This repository is a sample repo for wrapping the agnoStack API with secure encryption.
4+
5+
---
6+
7+
## Install
8+
9+
```bash
10+
nvm use
11+
yarn install
12+
```
13+
14+
## Setup env vars
15+
16+
Create a `.env` from the provided example.
17+
18+
```bash
19+
cp .env.example .env
20+
```
21+
22+
Enter values for `INTEGRATION_PUBLIC_KEY` and `BASE_API_PATH` given the values provided from agnoStack.
23+
24+
## Local testing
25+
26+
```bash
27+
yarn watch
28+
```
29+
30+
Post requests can then be made via `http://localhost:3000/dev/agnoStack/orders/12345`
31+
32+
## Deployment
33+
34+
```bash
35+
yarn deploy
36+
```
37+
38+
## Making requests
39+
40+
All requests must contain the following request headers, provided from agnoStack.
41+
42+
- x-organization-id
43+
- x-providerstack-id
44+
- x-client-id
45+
- x-client-secret
46+
47+
```bash
48+
curl --location --request POST 'http://localhost:3000/dev/agnoStack/orders/12345' \
49+
--header 'x-organization-id: YOUR_ORGANIZATION_ID' \
50+
--header 'x-client-id: YOUR_CLIENT_ID' \
51+
--header 'x-client-secret: YOUR_CLIENT_SECRET' \
52+
--header 'x-providerstack-id: YOUR_PROVIDERSTACK_ID'
53+
```

handlers.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const {
2+
getVerificationKeysData,
3+
prepareVerificationRequest,
4+
processVerificationResponse,
5+
} = require('@agnostack/verifyd')
6+
7+
const { BASE_API_PATH, INTEGRATION_PUBLIC_KEY } = process.env
8+
9+
const BASE_HEADERS = {
10+
'Content-Type': 'application/json',
11+
'Access-Control-Allow-Origin': '*',
12+
'Access-Control-Allow-Credentials': true,
13+
}
14+
15+
const proxy = async (event) => {
16+
let statusCode
17+
let body
18+
19+
try {
20+
const keysData = await getVerificationKeysData(INTEGRATION_PUBLIC_KEY)
21+
const _prepareVerificationRequest = prepareVerificationRequest({ keysData })
22+
const _processVerificationResponse = processVerificationResponse({ keysData })
23+
24+
const url = `${BASE_API_PATH}/${event?.pathParameters?.route}`
25+
const options = {
26+
method: 'POST',
27+
body: event?.body,
28+
headers: event?.headers,
29+
}
30+
31+
const [
32+
requestPath,
33+
requestOptions,
34+
derivedSecretKey
35+
] = await _prepareVerificationRequest(url, options) ?? []
36+
37+
const encryptedResponse = await fetch(requestPath, requestOptions).then((_response) => (
38+
_response.json()
39+
))
40+
41+
statusCode = 200
42+
body = await _processVerificationResponse(encryptedResponse, derivedSecretKey)
43+
} catch (error) {
44+
const message = 'Error proxying API request'
45+
console.error(message, error)
46+
47+
statusCode = 500
48+
body = { error: message }
49+
}
50+
51+
return { statusCode, body: JSON.stringify(body), headers: BASE_HEADERS }
52+
}
53+
54+
module.exports = { proxy }

package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"private": true,
3+
"name": "@agnostack/secure-api-proxy",
4+
"version": "1.0.0",
5+
"author": "agnoStack Dev <[email protected]> (https://agnostack.com)",
6+
"owner": "agnoStack",
7+
"description": "Please contact agnoStack via [email protected] for any questions",
8+
"license": "UNLICENSED",
9+
"homepage": "https://github.com/agnostack/secure-api-proxy/tree/develop#readme",
10+
"repository": "github:agnostack/secure-api-proxy",
11+
"engines": {
12+
"node": ">=18.x"
13+
},
14+
"scripts": {
15+
"deploy": "yarn serverless deploy",
16+
"watch": "yarn serverless offline"
17+
},
18+
"dependencies": {
19+
"@agnostack/verifyd": "latest"
20+
},
21+
"devDependencies": {
22+
"serverless": "3.x",
23+
"serverless-dotenv-plugin": "6.0.0",
24+
"serverless-offline": "12.x"
25+
}
26+
}

serverless.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
service: secure-api-proxy
2+
frameworkVersion: "3"
3+
4+
plugins:
5+
- serverless-dotenv-plugin
6+
- serverless-offline
7+
8+
custom:
9+
serverless-offline:
10+
reloadHandler: true
11+
12+
provider:
13+
name: aws
14+
runtime: nodejs18.x
15+
region: us-east-1
16+
17+
functions:
18+
proxy:
19+
handler: handlers.proxy
20+
events:
21+
- http:
22+
path: /agnoStack/{route+}
23+
method: post
24+
25+
resources:
26+
Resources:
27+
GatewayResponseDefault4XX:
28+
Type: 'AWS::ApiGateway::GatewayResponse'
29+
Properties:
30+
ResponseParameters:
31+
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
32+
gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
33+
ResponseType: DEFAULT_4XX
34+
RestApiId:
35+
Ref: 'ApiGatewayRestApi'
36+
GatewayResponseDefault5XX:
37+
Type: 'AWS::ApiGateway::GatewayResponse'
38+
Properties:
39+
ResponseParameters:
40+
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
41+
gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
42+
ResponseType: DEFAULT_5XX
43+
RestApiId:
44+
Ref: 'ApiGatewayRestApi'

0 commit comments

Comments
 (0)