Skip to content

Commit 15c23de

Browse files
authored
Merge pull request #497 from hack-a-chain-software/remove-cors
refactor: removed CORS origin handling
2 parents a5c2fd8 + 3d7a3a3 commit 15c23de

File tree

3 files changed

+0
-88
lines changed

3 files changed

+0
-88
lines changed

indexer/.env.example

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ DB_SSL_REJECT_UNAUTHORIZED=false
1111

1212
KADENA_GRAPHQL_API_PORT=3001 #optional
1313
SENTRY_DSN="http://sentryurl" #optional
14-
ALLOWED_ORIGINS=http://localhost:3001,http://localhost:3002,http://localhost:3003 #optional
1514
PRICE_CACHE_TTL=300 #optional

indexer/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ cp indexer/.env.template indexer/.env
5757
| `DB_SSL_ENABLED` | Enable/disable SSL for database | `true` or `false` |
5858
| `KADENA_GRAPHQL_API_PORT` | GraphQL API port | `3000` |
5959
| `SENTRY_DSN` | Sentry url to monitor indexer usage | `https://123.ingest.us.sentry.io/123` |
60-
| `ALLOWED_ORIGINS` | Allowed origins for CORS | `http://abcde:3001,http://abcde:3002` |
6160
| `PRICE_CACHE_TTL` | Time-to-live for price cache in seconds | `300` |
6261

6362
**NOTE:** The example Kadena node API from chainweb will not work for the indexer purpose. You will need to run your own Kadena node and set the `NODE_API_URL` to your node's API URL.

indexer/src/kadena-server/server.ts

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,6 @@ const typeDefs = readFileSync(join(__dirname, './config/schema.graphql'), 'utf-8
8484
*/
8585
const KADENA_GRAPHQL_API_PORT = process.env.KADENA_GRAPHQL_API_PORT ?? '3001';
8686

87-
/**
88-
* Array of domains allowed to access the GraphQL API
89-
*/
90-
91-
const ALLOWED_ORIGINS = getArrayEnvString('ALLOWED_ORIGINS');
92-
9387
/**
9488
* Apollo Server plugin that validates pagination parameters in GraphQL requests
9589
*
@@ -214,36 +208,6 @@ const securitySanitizationPlugin: ApolloServerPlugin = {
214208
}),
215209
};
216210

217-
/**
218-
* Checks if an origin is allowed to access the GraphQL API
219-
*
220-
* Implements CORS policy by validating origin domains against the allowed list.
221-
* Permits localhost for development and allows both exact matches and subdomains
222-
* of kadena.io.
223-
*
224-
* @param origin - The origin domain requesting access
225-
* @returns Boolean indicating if the origin is allowed
226-
*/
227-
const isAllowedOrigin = (origin: string): boolean => {
228-
try {
229-
const originUrl = new URL(origin);
230-
if (originUrl.hostname === 'localhost') return true;
231-
232-
return ALLOWED_ORIGINS.some(allowed => {
233-
const allowedUrl = new URL(allowed);
234-
// Check if it's an exact match
235-
if (originUrl.origin === allowedUrl.origin) return true;
236-
// Check if it's a subdomain (only for kadena.io)
237-
if (allowedUrl.hostname === 'kadena.io' && originUrl.hostname.endsWith('.kadena.io')) {
238-
return true;
239-
}
240-
return false;
241-
});
242-
} catch {
243-
return false;
244-
}
245-
};
246-
247211
/**
248212
* Initializes and starts the GraphQL server
249213
*
@@ -515,20 +479,6 @@ export async function startGraphqlServer() {
515479
app.use(
516480
'/graphql',
517481
cors<cors.CorsRequest>({
518-
origin: (origin, callback) => {
519-
if (!origin || origin === 'null') {
520-
return callback(null, false);
521-
}
522-
523-
try {
524-
if (isAllowedOrigin(origin)) {
525-
return callback(null, true);
526-
}
527-
return callback(new Error(`[ERROR][CORS][ORIGIN] Origin ${origin} not allowed by CORS`));
528-
} catch (error) {
529-
return callback(null, false);
530-
}
531-
},
532482
methods: ['POST', 'OPTIONS'],
533483
allowedHeaders: [
534484
'Content-Type',
@@ -548,42 +498,6 @@ export async function startGraphqlServer() {
548498
}),
549499
);
550500

551-
/**
552-
* Handle CORS preflight OPTIONS requests explicitly
553-
*
554-
* This endpoint manages the CORS preflight requests that browsers send before making
555-
* actual API requests. It's a critical security component that:
556-
*
557-
* 1. Validates the origin against the allowed domains list
558-
* 2. Sets appropriate CORS headers when origins are allowed:
559-
* - Access-Control-Allow-Origin: Reflects the allowed origin
560-
* - Access-Control-Allow-Credentials: Enables authenticated requests
561-
* - Access-Control-Allow-Methods: Limits to POST and OPTIONS methods
562-
* - Access-Control-Allow-Headers: Specifies allowed request headers
563-
* - Access-Control-Max-Age: Caches preflight result for 24 hours (86400s)
564-
* 3. Returns 204 No Content for allowed origins or 403 Forbidden for disallowed ones
565-
*
566-
* This explicit handling ensures precise control over cross-origin security,
567-
* preventing unauthorized domains from accessing the API while allowing
568-
* legitimate client applications to function properly.
569-
*/
570-
app.options('*', (req: Request, res: Response) => {
571-
const origin = req.headers.origin;
572-
if (origin && isAllowedOrigin(origin)) {
573-
res.setHeader('Access-Control-Allow-Origin', origin);
574-
res.setHeader('Access-Control-Allow-Credentials', 'true');
575-
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
576-
res.setHeader(
577-
'Access-Control-Allow-Headers',
578-
'Content-Type, Authorization, Accept, Origin, X-Requested-With, Cache-Control, Pragma',
579-
);
580-
res.setHeader('Access-Control-Max-Age', '86400');
581-
res.status(204).end();
582-
} else {
583-
res.status(403).end();
584-
}
585-
});
586-
587501
/**
588502
* Handle 404 Not Found errors for all other routes
589503
*

0 commit comments

Comments
 (0)