-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Description Adds a get notified tag and form and privacy policy - Closes #18 ## Type of change Please delete options that are not relevant. - [x] Content Change (Required approval in Slack: `#frequency-xyz` and remember that changes along the way trigger re-approval.) - [x] Approved HE (Required for technical wording) - [x] Approved CM - [x] New Feature # How to Test? Please describe how to test that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration 1. Pull and run locally 2. See that the get notified button on the right doesn't cover important text 3. Click the button and see that it loads the form 4. Form errors 5. Thank you after submitting the form # Checklist: - [x] I have performed a self-review of my code - [ ] I have commented my code & PR, particularly in hard-to-understand areas - [x] I have checked at all the breakpoints to make sure it works on all screen sizes
- Loading branch information
Showing
27 changed files
with
1,050 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Serverless CORS Proxy | ||
|
||
This is a simple serverless CORS proxy that supports `POST` requests. | ||
|
||
This is used by the contact form. | ||
|
||
## Features | ||
|
||
- Supports `POST` requests to a single `PROXY_TARGET_URL` | ||
- Adds CORS headers for cross-origin requests | ||
|
||
## Serverless.yaml | ||
|
||
See [./serverless.yaml] to use [serverless.com config](https://www.serverless.com/) | ||
|
||
## Environment Variables | ||
|
||
These are the environment variables used by the handler. | ||
|
||
- `PROXY_TARGET_URL`: Where the proxy will redirect the requests to | ||
- `PROXY_ALLOWED_ORIGIN`: (Default `'*'`) The `Access-Control-Allow-Origin` string for the local server. | ||
|
||
## Setup | ||
|
||
### 1. Running Locally | ||
|
||
To run the CORS proxy locally: | ||
|
||
1. Run the proxy locally: | ||
|
||
```bash | ||
PROXY_TARGET_URL="https://example.com/submit-form" npm run start | ||
``` | ||
|
||
- Replace `https://example.com/submit-form` with the target URL. | ||
|
||
2. Use the following `curl` example to test a `POST` request from your terminal: | ||
|
||
```bash | ||
curl -X POST "http://localhost:3000/" \ | ||
-d "param1=value1¶m2=value2" | ||
``` | ||
|
||
- Replace `param1=value1¶m2=value2` with your actual form data. | ||
|
||
### 2. Using with an HTML Form and JavaScript Fetch | ||
|
||
You can use this proxy to submit a form using JavaScript `fetch`. Here’s an example: | ||
|
||
#### HTML Form: | ||
|
||
```html | ||
<form id="exampleForm"> | ||
<input type="text" name="param1" value="value1" /> | ||
<input type="text" name="param2" value="value2" /> | ||
<button type="submit">Submit</button> | ||
</form> | ||
|
||
<script> | ||
document.getElementById('exampleForm').addEventListener('submit', async (e) => { | ||
e.preventDefault(); // Prevent the default form submission | ||
const formData = new FormData(e.target); | ||
const params = new URLSearchParams(formData).toString(); | ||
try { | ||
const response = await fetch('https://localhost:3000', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
body: params, | ||
}); | ||
const result = await response.json(); | ||
console.log(result); // Handle the response | ||
} catch (error) { | ||
console.error('Error:', error); | ||
} | ||
}); | ||
</script> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import https from 'node:https'; | ||
import process from 'node:process'; | ||
|
||
export const handler = async (event) => { | ||
const targetUrl = process.env.PROXY_TARGET_URL; | ||
|
||
const postData = event.body; | ||
|
||
const options = { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
}; | ||
|
||
return new Promise((resolve, _reject) => { | ||
const req = https.request(targetUrl, options, (response) => { | ||
let data = ''; | ||
|
||
// Collect response data | ||
response.on('data', (chunk) => (data += chunk)); | ||
|
||
// When the request is complete | ||
response.on('end', () => { | ||
resolve({ | ||
statusCode: 200, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
status: response.statusCode, | ||
headers: response.headers, | ||
body: data, | ||
}), | ||
}); | ||
}); | ||
}); | ||
|
||
req.on('error', (error) => { | ||
resolve({ | ||
statusCode: 500, | ||
body: JSON.stringify({ message: 'Error in request', error: error.message }), | ||
}); | ||
}); | ||
|
||
req.write(postData); | ||
req.end(); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "cors-proxy", | ||
"type": "module", | ||
"version": "1.0.0", | ||
"description": "A simple CORS proxy for serverless environments.", | ||
"main": "index.mjs", | ||
"scripts": { | ||
"start": "node server.mjs" | ||
}, | ||
"dependencies": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import http from 'http'; | ||
import { handler } from './index.mjs'; | ||
import url from 'url'; | ||
import process from 'node:process'; | ||
|
||
const allowedOrigin = process.env.PROXY_ALLOWED_ORIGIN || '*'; | ||
|
||
// Function to parse the HTTP request body | ||
const getRequestBody = (req) => { | ||
return new Promise((resolve, reject) => { | ||
let body = ''; | ||
req.on('data', (chunk) => { | ||
body += chunk.toString(); | ||
}); | ||
req.on('end', () => { | ||
resolve(body); | ||
}); | ||
req.on('error', (err) => { | ||
reject(err); | ||
}); | ||
}); | ||
}; | ||
|
||
// Start the HTTP server | ||
const server = http.createServer(async (req, res) => { | ||
// Set CORS headers | ||
res.setHeader('Access-Control-Allow-Origin', allowedOrigin); | ||
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); | ||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); | ||
|
||
// Handle OPTIONS request for CORS preflight | ||
if (req.method === 'OPTIONS') { | ||
res.writeHead(200); | ||
res.end(); | ||
return; | ||
} | ||
|
||
if (req.method === 'POST') { | ||
const parsedUrl = url.parse(req.url, true); | ||
const body = await getRequestBody(req); | ||
|
||
// Convert HTTP request into a Lambda event format | ||
const lambdaEvent = { | ||
httpMethod: req.method, | ||
queryStringParameters: parsedUrl.query, | ||
body: body, | ||
}; | ||
|
||
// Call the handler (same code used in AWS Lambda) | ||
const lambdaResponse = await handler(lambdaEvent); | ||
|
||
// Send response | ||
res.writeHead(lambdaResponse.statusCode, { | ||
...lambdaResponse.headers, | ||
'Access-Control-Allow-Origin': '*', // Make sure to include CORS in response too | ||
}); | ||
res.end(lambdaResponse.body); | ||
} else { | ||
res.statusCode = 405; | ||
res.end('Only POST requests are supported'); | ||
} | ||
}); | ||
|
||
// Start server on port 3000 | ||
server.listen(3000, () => { | ||
console.log('Local server running on http://localhost:3000'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
service: xyz-form-cors-proxy | ||
|
||
frameworkVersion: '4' | ||
|
||
provider: | ||
name: aws | ||
runtime: nodejs20.x | ||
|
||
functions: | ||
hello: | ||
handler: handler.handler | ||
events: | ||
- http: | ||
method: post | ||
cors: | ||
origin: 'https://*.frequency.xyz' | ||
headers: | ||
- Content-Type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
<footer class="freq-container flex h-[50px] items-center justify-end gap-3 text-xs font-semibold"> | ||
<div>© {new Date().getFullYear()} Frequency Network Foundation</div> | ||
<span class="h-4 w-[2px] bg-black" /> | ||
<a href="/privacy">Privacy Policy</a> | ||
<span class="h-4 w-[2px] bg-black" /> | ||
<div class="whitespace-nowrap">All Rights Reserved</div> | ||
</footer> |
Oops, something went wrong.