Skip to content

Commit ff02889

Browse files
authored
Merge pull request #206 from 0xneves/v0/refactor-cors
feat: only the gateway is authorized via wss and cors
2 parents 31696fd + 57d23cd commit ff02889

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

indexer/.env.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ SYNC_NETWORK="mainnet01"
77
KADENA_GRAPHQL_API_URL=localhost
88
KADENA_GRAPHQL_API_PORT=3001
99

10+
API_GATEWAY_URL=https://api.mainnet.kadindexer.io
11+
1012
DB_USERNAME=postgres
1113
DB_PASSWORD=password
1214
DB_NAME=indexer

indexer/src/kadena-server/server.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@ const typeDefs = readFileSync(join(__dirname, './config/schema.graphql'), 'utf-8
3131

3232
const KADENA_GRAPHQL_API_PORT = getRequiredEnvString('KADENA_GRAPHQL_API_PORT');
3333

34+
const ALLOWED_ORIGINS = [
35+
getRequiredEnvString('API_GATEWAY_URL'),
36+
`http://localhost:${KADENA_GRAPHQL_API_PORT}`,
37+
];
38+
3439
const validatePaginationParamsPlugin: ApolloServerPlugin = {
3540
requestDidStart: async () => ({
3641
didResolveOperation: async ({ request, document }) => {
3742
const variables = { ...request.variables }; // External variables
43+
// prettier-ignore
3844
const inlineArguments: Record<string, any> = {};
3945

4046
// Helper function to extract inline arguments
@@ -136,6 +142,20 @@ export async function useKadenaGraphqlServer() {
136142
const wsServer = new WebSocketServer({
137143
server: httpServer,
138144
path: '/graphql',
145+
verifyClient: ({ origin }, callback) => {
146+
if (!origin || origin === 'null') {
147+
return callback(false, 400, 'No origin');
148+
}
149+
try {
150+
const url = new URL(origin);
151+
if (ALLOWED_ORIGINS.includes(url.origin)) {
152+
return callback(true);
153+
}
154+
return callback(false, 403, 'Forbidden');
155+
} catch {
156+
return callback(false, 400, 'Invalid origin');
157+
}
158+
},
139159
});
140160

141161
const serverCleanup = useServer(
@@ -160,7 +180,27 @@ export async function useKadenaGraphqlServer() {
160180

161181
app.use(
162182
'/graphql',
163-
cors<cors.CorsRequest>(),
183+
cors<cors.CorsRequest>({
184+
origin: (origin, callback) => {
185+
if (!origin || origin === 'null') {
186+
return callback(null, false);
187+
}
188+
189+
try {
190+
const url = new URL(origin);
191+
if (ALLOWED_ORIGINS.includes(url.origin)) {
192+
return callback(null, true);
193+
}
194+
return callback(new Error(`Origin ${origin} not allowed by CORS`));
195+
} catch (error) {
196+
return callback(null, false);
197+
}
198+
},
199+
methods: ['POST', 'OPTIONS'],
200+
allowedHeaders: ['Content-Type', 'Authorization'],
201+
// When using credentials: true, you cannot use * for Access-Control-Allow-Origin. You must specify exact origins.
202+
credentials: true,
203+
}),
164204
expressMiddleware(server, {
165205
context: createGraphqlContext,
166206
}),

0 commit comments

Comments
 (0)