-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add request signing and Next js app base
- Loading branch information
1 parent
a56ddaa
commit 78bb863
Showing
28 changed files
with
13,244 additions
and
5,896 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,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
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,45 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.yarn/install-state.gz | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
# Temporary Edgio files | ||
.edgio | ||
|
||
# Node.js modules | ||
node_modules | ||
|
||
# Edgio generated build directory | ||
.edgio |
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 |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import '../../utils/polyfills/URL'; | ||
|
||
export async function handleHttpRequest(request, context) { | ||
// Retrieve the client's IP address from the context object | ||
const clientIP = context.client.dst_addr; | ||
|
||
const newRequest = new Request(request.url, request); | ||
|
||
// Add the true-client-ip header to the incoming request | ||
newRequest.headers.set('true-client-ip', clientIP); | ||
|
||
// Continue with the modified request | ||
return fetch(newRequest, { | ||
edgio: { origin: 'echo' }, | ||
}); | ||
} |
18 changes: 18 additions & 0 deletions
18
examples/v7-edge-functions/functions/general/redirect-country.js
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 @@ | ||
export async function handleHttpRequest(request, context) { | ||
const country = 'DE'; // Choose a country code | ||
const newUrl = `${request.url}/${country}`; // Change the redirect URL to your choice | ||
|
||
if (context.geo.country === country) { | ||
return new Response(null, { | ||
status: 302, | ||
statusText: 'Found', | ||
headers: { | ||
Location: newUrl, | ||
}, | ||
}); | ||
} | ||
|
||
return fetch(request.url, { | ||
edgio: { origin: 'echo' }, | ||
}); | ||
} |
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
25 changes: 25 additions & 0 deletions
25
examples/v7-edge-functions/functions/general/security-response-headers.js
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,25 @@ | ||
export async function handleHttpRequest(request, context) { | ||
// Fetch the response from the 'echo' origin | ||
const response = await fetch(new Request(request.url, request), { | ||
edgio: { | ||
origin: 'echo', | ||
}, | ||
}); | ||
|
||
// Set HTTP security headers | ||
response.headers.set( | ||
'strict-transport-security', | ||
'max-age=63072000; includeSubdomains; preload' | ||
); | ||
response.headers.set( | ||
'content-security-policy', | ||
"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'; frame-ancestors 'none'" | ||
); | ||
response.headers.set('x-content-type-options', 'nosniff'); | ||
response.headers.set('x-frame-options', 'DENY'); | ||
response.headers.set('x-xss-protection', '1; mode=block'); | ||
response.headers.set('referrer-policy', 'same-origin'); | ||
|
||
// Return the response to the client | ||
return response; | ||
} |
54 changes: 54 additions & 0 deletions
54
examples/v7-edge-functions/functions/general/signed-request/sign.js
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,54 @@ | ||
import '../../../utils/polyfills/URL'; | ||
import HmacSHA1 from 'crypto-js/hmac-sha1'; | ||
import Base64 from 'crypto-js/enc-base64'; | ||
|
||
export async function handleHttpRequest(request, context) { | ||
// ** IMPORTANT ** | ||
// Secret key should be defined as an environment variable in the Edgio console | ||
const secretKey = '$0m3th!ngS3cr3t'; // contet.environmentVars.REQ_SIGNING_SECRET_KEY; | ||
|
||
return generateSignedUrl(new URL(request.url), secretKey); | ||
} | ||
|
||
async function generateSignedUrl(url, key) { | ||
// Replace /sign/ with /verify/ in the URL since we are generating a signed URL for verification | ||
url.pathname = url.pathname.replace('/sign/', '/verify/'); | ||
|
||
// The link will expire in 5 minutes | ||
const expirationMs = 1000 * 60 * 5; // 5 minutes | ||
const expiry = Date.now() + expirationMs; | ||
const dataToAuthenticate = url.pathname + expiry; | ||
|
||
const hash = HmacSHA1(dataToAuthenticate, secretKey); | ||
const base64Mac = Base64.stringify(hash); | ||
|
||
url.searchParams.set('mac', base64Mac); | ||
url.searchParams.set('expiry', expiry.toString()); | ||
|
||
const validUrl = url.toString(); | ||
const modifiedExpiryUrl = new URL(validUrl); | ||
modifiedExpiryUrl.searchParams.set('expiry', `${expiry + 5}`); | ||
const modifiedMacUrl = new URL(validUrl); | ||
modifiedMacUrl.searchParams.set('mac', `${base64Mac}x`); | ||
|
||
console.log('Valid URL:\n', validUrl); | ||
console.log('Modified expiry URL:\n', modifiedExpiryUrl.toString()); | ||
console.log('Modified MAC URL:\n', modifiedMacUrl.toString()); | ||
|
||
const htmlResponse = ` | ||
<html> | ||
<body> | ||
<p>Click the following links for verification:</p> | ||
<ul> | ||
<li><a href="${validUrl}">Valid URL</a><pre>(${validUrl})</pre></li> | ||
<li><a href="${modifiedExpiryUrl}">Invalid with modified Expiry URL</a><pre>(${modifiedExpiryUrl})</pre></li> | ||
<li><a href="${modifiedMacUrl}">Invalid with modified Mac URL</a><pre>(${modifiedMacUrl})</pre></li> | ||
</ul> | ||
</body> | ||
</html> | ||
`; | ||
|
||
return new Response(htmlResponse, { | ||
headers: { 'Content-Type': 'text/html' }, | ||
}); | ||
} |
60 changes: 60 additions & 0 deletions
60
examples/v7-edge-functions/functions/general/signed-request/verify.js
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,60 @@ | ||
import '../../../utils/polyfills/URL'; | ||
import { setEnvFromContext } from '../../../utils/polyfills/process.env'; | ||
import createFetchForOrigin from '../../../utils/createFetchForOrigin'; | ||
import HmacSHA256 from 'crypto-js/hmac-sha256'; | ||
import Base64 from 'crypto-js/enc-base64'; | ||
|
||
const fetch = createFetchForOrigin('echo'); | ||
|
||
export async function handleHttpRequest(request, context) { | ||
// Set environment variables from the request context | ||
setEnvFromContext(context); | ||
|
||
return verifyAndFetch(new Request(request.url, request)); | ||
} | ||
|
||
async function verifyAndFetch(request) { | ||
// ** IMPORTANT ** | ||
// Secret key should be defined as an environment variable in the Edgio console | ||
const secretKey = '$0m3th!ngS3cr3t'; // process.env.REQ_SIGNING_SECRET_KEY; | ||
|
||
const url = new URL(request.url); | ||
|
||
if (!url.searchParams.has('mac') || !url.searchParams.has('expiry')) { | ||
return new Response('Missing query parameter', { status: 403 }); | ||
} | ||
|
||
const expiry = Number(url.searchParams.get('expiry')); | ||
const dataToAuthenticate = url.pathname + expiry; | ||
|
||
const receivedMacBase64 = url.searchParams.get('mac'); | ||
const receivedMac = Base64.parse(receivedMacBase64); | ||
|
||
const hash = HmacSHA256(dataToAuthenticate, secretKey); | ||
const hashInBase64 = Base64.stringify(hash); | ||
|
||
if (hashInBase64 !== receivedMacBase64) { | ||
return new Response( | ||
JSON.stringify( | ||
{ | ||
message: 'Invalid MAC', | ||
hashInBase64, | ||
receivedMacBase64, | ||
}, | ||
null, | ||
2 | ||
), | ||
{ status: 403 } | ||
); | ||
} | ||
|
||
if (Date.now() > expiry) { | ||
const body = `URL expired at ${new Date(expiry)}`; | ||
return new Response(body, { status: 403 }); | ||
} | ||
|
||
// Forward the remaining request path after **/verify/* to the origin | ||
url.pathname = url.pathname.split('/verify/')[1]; | ||
|
||
return fetch(url.toString()); | ||
} |
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,8 @@ | ||
{ | ||
"compilerOptions": { | ||
"jsx": "react", | ||
"paths": { | ||
"@/*": ["./src/*"] | ||
} | ||
} | ||
} |
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,13 @@ | ||
// This file was automatically added by edgio init. | ||
// You should commit this file to source control. | ||
const { withEdgio } = require('@edgio/next/config') | ||
|
||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = {} | ||
|
||
const _preEdgioExport = nextConfig;; | ||
|
||
module.exports = (phase, config) => | ||
withEdgio({ | ||
..._preEdgioExport | ||
}) |
Oops, something went wrong.