diff --git a/cors-proxy/README.md b/cors-proxy/README.md new file mode 100644 index 00000000..0dd31093 --- /dev/null +++ b/cors-proxy/README.md @@ -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 +
+ + +``` diff --git a/cors-proxy/index.mjs b/cors-proxy/index.mjs new file mode 100644 index 00000000..a7242e39 --- /dev/null +++ b/cors-proxy/index.mjs @@ -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(); + }); +}; diff --git a/cors-proxy/package.json b/cors-proxy/package.json new file mode 100644 index 00000000..f7eb83e3 --- /dev/null +++ b/cors-proxy/package.json @@ -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": {} +} diff --git a/cors-proxy/server.mjs b/cors-proxy/server.mjs new file mode 100644 index 00000000..63250a5b --- /dev/null +++ b/cors-proxy/server.mjs @@ -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'); +}); diff --git a/cors-proxy/serverless.yaml b/cors-proxy/serverless.yaml new file mode 100644 index 00000000..36436708 --- /dev/null +++ b/cors-proxy/serverless.yaml @@ -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 diff --git a/src/app.html b/src/app.html index 8f37ae9c..7901cc35 100644 --- a/src/app.html +++ b/src/app.html @@ -8,7 +8,7 @@ - + @@ -35,8 +35,8 @@ %sveltekit.head% - - + + + +Get notified when more developer tools are available.
+Become a part of shaping the future of the digital landscape with Frequency.
++ Last Updated: September 16, 2024 +
++ This Privacy Notice applies to the processing of personal information by the Frequency Network Foundation (“Frequency Network Foundation,” “we,” “us,” or “our”) in connection with our website at + https://www.frequency.xyz (the “Site”). +
+
+ However, this Privacy Notice
+ Aspects of the Site may be hosted on or interact with the blockchain, including Frequency, a layer 1 blockchain + integrated into the Polkadot platform (“Frequency Network”). Where you use aspects of the Site that are hosted on + or interact with the blockchain, information about your interactions and/or transactions will be provided to the + applicable blockchain network and may be accessible to third parties due to the nature of the blockchain protocol. +
++ We may update this Privacy Notice from time to time in our sole discretion. If we do, we’ll let you know by + posting the updated Privacy Notice on our website, and/or we may also send other communications. +
++ We collect personal information that you provide to us, personal information we obtain automatically when you + interact with the Site, and personal information from third-party sources, as described below. +
+We may collect personal information that you provide to us.
+We may collect personal information automatically when you use or interact with the Site.
++ See “Your Privacy Choices and Rights” below to understand your choices + regarding these Technologies. +
++ We may collect personal information from other sources, including third-party services and publicly available + sources. Third-party services include the eligible platforms (e.g., social media networks) that have been + approved to participate in the Site and with whom you have a user account (“Providers”). +
++ We use the hCaptcha security service ("hCaptcha"). hCaptcha is used to check whether data + submitted on the Site website (such as submitting a login or contact form) has been entered by a human or by an + automated program. For more information about hCaptcha’s privacy policy and terms of use, please visit the + following links: https://www.hcaptcha.com/privacy and + https://www.hcaptcha.com/terms +
++ We use personal information for a variety of business purposes, including to operate the Site, for administrative + purposes, and to provide you with marketing materials, as described below. +
+We use personal information to fulfill our contract with you and operate the Site, such as:
+We use personal information for various administrative purposes, such as:
++ We may use personal information to provide you with marketing about the Frequency Network Foundation and/or the + Site. We may provide you with these materials as permitted by applicable law. +
++ If you have any questions about our marketing practices, you may contact us at any time as set forth in “Contact Us” below. +
++ We may use personal information for other purposes that are clearly disclosed to you at the time you provide + personal information or with your consent. +
+We also use personal information for other purposes as requested by you or as permitted by applicable law.
++ We disclose personal information to third parties for a variety of business purposes, including to operate the + Program, to protect us or others, or in the event of a major business transaction such as a merger, sale, or asset + transfer, as described below. +
+The categories of third parties with whom we may share your personal information are described below.
++ For example, if you join the Frequency Discord, Discord may collect any personal information you provide or + otherwise make available via that channel. +
++ If you share information or interact with a Third-Party Service, the information collected by the Third-Party + Service will also be subject to the Third-Party Service’s privacy policy. +
++ We may access, preserve, and disclose any information we store associated with you to external parties if we, in + good faith, believe doing so is required or appropriate to: comply with law enforcement or national security + requests and legal process, such as a court order or subpoena; protect your, our, or others’ rights, property, or + safety; enforce our policies or contracts; collect amounts owed to us; or assist with an investigation or + prosecution of suspected or actual illegal activity. +
++ If we are involved in a merger, acquisition, financing, reorganization, bankruptcy, receivership, purchase or sale + of assets, transition of service to another provider, or other similar corporate transaction, your personal + information may be disclosed, sold, or transferred as part of such a transaction. +
++ Your Privacy Choices. The privacy choices you may have about your personal information are + determined by applicable law and are described below. +
+Please note you must separately opt out in each browser and on each device.
++ Your Privacy Rights. In accordance with applicable law, you may have the right to: +
++ If you would like to exercise any of these rights, please contact us as set forth in “Contact Us” below. We will + process such requests in accordance with applicable laws. +
++ If your personal information is subject to the applicable data protection laws of the European Economic Area or + Switzerland you have the right to lodge a complaint with the competent supervisory authority if you believe our + processing of your personal information violates applicable law. +
++ All personal information processed by us may be transferred, processed, and stored anywhere in the world, + including, but not limited to, the United States or other countries, which may have data protection laws that are + different from the laws where you live. These countries may or may not have adequate data protection laws as + defined by the data protection authority in your country. +
++ If we transfer personal information which originates in the European Economic Area and/or Switzerland to a country + that has not been found to provide an adequate level of protection under applicable data protection laws, one of + the safeguards we may use to support such transfer is the EU Standard Contractual Clauses. +
++ For more information about the safeguards we use for international transfers of your personal information, please + contact us as set forth below. +
++ We store the personal information we collect as described in this Privacy Notice for as long as you participate in + the Site, or as necessary to fulfill the purpose(s) for which it was collected, operate the Site, resolve + disputes, establish legal defenses, conduct audits, pursue legitimate business purposes, enforce our agreements, + and comply with applicable laws. +
++ To determine the appropriate retention period for personal information, we may consider applicable legal + requirements, the amount, nature, and sensitivity of the personal information, certain risk factors, the purposes + for which we process your personal information, and whether we can achieve those purposes through other means. +
++ This Supplemental Notice for EU GDPR only applies to our processing of personal information that is subject to the + EU GDPR. +
++ The Frequency Network Foundation’s processing of your personal information may be supported by one or more of the + following legal bases: +
++ The Site is not directed to children under 13 (or other age as required by local law outside the United States), + and we do not knowingly collect personal information from children. +
++ If you are a parent or guardian and believe your child has uploaded personal information to our site without your + consent, you may contact us as described in “Contact Us” below. If we become + aware that a child has provided us with personal information in violation of applicable law, we will delete any + personal information we have collected, unless we have a legal obligation to keep it, and terminate the child’s + account, if applicable. +
++ The Site may contain links to other websites/applications and other websites/applications may reference or link to + our Site. These third-party services are not controlled by us. We encourage our users to read the privacy policies + of each website and application with which they interact. We do not endorse, screen, or approve, and are not + responsible for, the privacy practices or content of such other websites or applications. Providing personal + information to third-party websites or applications is at your own risk. +
++ The Frequency Network Foundation is the controller of the personal information we process under this Privacy + Notice. +
++ If you have any questions about our privacy practices or this Privacy Notice, or to exercise your rights as + detailed in this Privacy Notice, please contact us at: privacy@frequency.xyz. +
+