Skip to content

Commit e80ca0b

Browse files
Allowing Vercel preview URLs
1 parent df2a700 commit e80ca0b

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

docs-v2/.env.example

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
# Pipedream Connect SDK credentials
2-
PIPEDREAM_PROJECT_ID=
3-
PIPEDREAM_CLIENT_ID=
4-
PIPEDREAM_CLIENT_SECRET=
5-
PIPEDREAM_PROJECT_ENVIRONMENT=
1+
# Connect demo API configuration
2+
PIPEDREAM_CLIENT_ID=your_client_id
3+
PIPEDREAM_CLIENT_SECRET=your_client_secret
4+
PIPEDREAM_PROJECT_ID=your_project_id
5+
PIPEDREAM_PROJECT_ENVIRONMENT=development
66

7-
# Not required
7+
# Additional redirect URIs for the Connect demo (optional)
88
PIPEDREAM_CONNECT_TOKEN_WEBHOOK_URI=
99
PIPEDREAM_CONNECT_SUCCESS_REDIRECT_URI=
1010
PIPEDREAM_CONNECT_ERROR_REDIRECT_URI=
11+
12+
# Comma-separated list of additional allowed origins (optional)
13+
# ALLOWED_ORIGINS=https://your-custom-domain.com,https://another-domain.com

docs-v2/pages/api/demo-connect/token.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ async function tokenHandler(req, res) {
5050
},
5151
body: JSON.stringify({
5252
external_user_id,
53-
allowed_origins: ALLOWED_ORIGINS,
53+
// Use only the list of origins for the API, not the helper object
54+
allowed_origins: ALLOWED_ORIGINS.originsList,
5455
webhook_uri: process.env.PIPEDREAM_CONNECT_TOKEN_WEBHOOK_URI,
5556
success_redirect_uri: process.env.PIPEDREAM_CONNECT_SUCCESS_REDIRECT_URI,
5657
error_redirect_uri: process.env.PIPEDREAM_CONNECT_ERROR_REDIRECT_URI,

docs-v2/pages/api/demo-connect/utils.js

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,50 @@
22
* Shared utilities for Connect demo API routes
33
*/
44

5-
// Allowed origins for CORS security
6-
export const ALLOWED_ORIGINS = [
7-
"https://pipedream.com",
8-
"https://www.pipedream.com",
9-
"http://localhost:3000", // For local development
10-
];
5+
/**
6+
* Get allowed origins from environment variables or use defaults
7+
* This supports Vercel preview deployments with their dynamic URLs
8+
*/
9+
export function getAllowedOrigins() {
10+
// Get from environment if defined
11+
const originsFromEnv = process.env.ALLOWED_ORIGINS
12+
? process.env.ALLOWED_ORIGINS.split(",").map((origin) => origin.trim())
13+
: [];
14+
15+
// Default allowed origins
16+
const defaultOrigins = [
17+
"https://pipedream.com",
18+
"https://www.pipedream.com",
19+
"http://localhost:3000", // For local development
20+
];
21+
22+
// Vercel preview deployment support - match any Vercel preview URL
23+
const vercelPreviewRegexes = [
24+
/^https:\/\/[a-zA-Z0-9-]+-[a-zA-Z0-9-]+-[a-zA-Z0-9-]+\.vercel\.app$/,
25+
];
26+
27+
return {
28+
originsList: [
29+
...defaultOrigins,
30+
...originsFromEnv,
31+
],
32+
regexPatterns: vercelPreviewRegexes,
33+
34+
// Helper method to check if an origin is allowed
35+
isAllowed(origin) {
36+
if (!origin) return false;
37+
38+
// Check exact matches
39+
if (this.originsList.includes(origin)) return true;
40+
41+
// Check regex patterns
42+
return this.regexPatterns.some((pattern) => pattern.test(origin));
43+
},
44+
};
45+
}
46+
47+
// Export the helper for consistent use
48+
export const ALLOWED_ORIGINS = getAllowedOrigins();
1149

1250
/**
1351
* Generate a browser-specific token based on request properties
@@ -22,9 +60,10 @@ export function generateRequestToken(req) {
2260
* Sets CORS headers for API responses
2361
*/
2462
export function setCorsHeaders(req, res, methods = "GET, POST, OPTIONS") {
63+
// Use the new isAllowed method to check if the origin is allowed
2564
res.setHeader(
2665
"Access-Control-Allow-Origin",
27-
ALLOWED_ORIGINS.includes(req.headers.origin)
66+
ALLOWED_ORIGINS.isAllowed(req.headers.origin)
2867
? req.headers.origin
2968
: "",
3069
);
@@ -42,16 +81,21 @@ export function validateRequest(req, res, allowedMethod) {
4281
const requestToken = req.headers["x-request-token"];
4382

4483
// Origin validation
45-
if (origin && !ALLOWED_ORIGINS.includes(origin)) {
84+
if (origin && !ALLOWED_ORIGINS.isAllowed(origin)) {
4685
return res.status(403).json({
4786
error: "Access denied",
4887
});
4988
}
5089

51-
// Referer validation
90+
// Referer validation for docs context
5291
if (
5392
referer &&
54-
!ALLOWED_ORIGINS.some((allowed) => referer.startsWith(allowed)) &&
93+
// Check if referer starts with any allowed origin
94+
!ALLOWED_ORIGINS.originsList.some((allowed) => referer.startsWith(allowed)) &&
95+
// Check if referer matches any regex pattern
96+
!ALLOWED_ORIGINS.regexPatterns.some((pattern) =>
97+
pattern.test(referer.split("/")[0] + "//" + referer.split("/")[2])) &&
98+
// Allow if it contains the docs path
5599
!referer.includes("/docs/connect/")
56100
) {
57101
return res.status(403).json({

0 commit comments

Comments
 (0)