diff --git a/packages/brain/src/index.ts b/packages/brain/src/index.ts index e81c88d9..4e995e4a 100644 --- a/packages/brain/src/index.ts +++ b/packages/brain/src/index.ts @@ -60,7 +60,8 @@ const { uiServer, launchpadServer, brainApiServer } = getServers({ validatorApi, beaconchainApi, brainDb, - reloadValidatorsCronTask + reloadValidatorsCronTask, + allowedOriginsFromEnv: config.apis.cors }); // Graceful shutdown diff --git a/packages/brain/src/modules/apiServers/brain/config.ts b/packages/brain/src/modules/apiServers/brain/config.ts index 0cd05b0d..f33e144c 100644 --- a/packages/brain/src/modules/apiServers/brain/config.ts +++ b/packages/brain/src/modules/apiServers/brain/config.ts @@ -1,3 +1 @@ -export const corsOptions = { - origin: ["http://csm-lido.dappnode", "http://csm-lido.testnet.dappnode"] // TODO: update with DAppNodePackage-lido-csm.dnp.dappnode.eth domains -}; +export const allowedOrigins = ["http://ui.lido-csm-holesky.dappnode", "http://ui.lido-csm-mainnet.dappnode"]; diff --git a/packages/brain/src/modules/apiServers/brain/startBrainApi.ts b/packages/brain/src/modules/apiServers/brain/startBrainApi.ts index 576f7517..987b1f19 100644 --- a/packages/brain/src/modules/apiServers/brain/startBrainApi.ts +++ b/packages/brain/src/modules/apiServers/brain/startBrainApi.ts @@ -3,14 +3,20 @@ import cors from "cors"; import logger from "../../logger/index.js"; import http from "node:http"; import { params } from "../../../params.js"; -import { corsOptions } from "./config.js"; +import { allowedOrigins } from "./config.js"; import { createBrainValidatorsRouter } from "./routes/index.js"; import { BrainDataBase } from "../../db/index.js"; -export function startBrainApi({ brainDb }: { brainDb: BrainDataBase }): http.Server { +export function startBrainApi({ + brainDb, + allowedOriginsFromEnv +}: { + brainDb: BrainDataBase; + allowedOriginsFromEnv: string[] | null; +}): http.Server { const app = express(); app.use(express.json()); - app.use(cors(corsOptions)); + app.use(cors({ origin: allowedOriginsFromEnv ?? allowedOrigins })); app.use(createBrainValidatorsRouter({ brainDb })); diff --git a/packages/brain/src/modules/apiServers/index.ts b/packages/brain/src/modules/apiServers/index.ts index 7af60b20..d30a6ffd 100644 --- a/packages/brain/src/modules/apiServers/index.ts +++ b/packages/brain/src/modules/apiServers/index.ts @@ -20,7 +20,8 @@ export const getServers = ({ validatorApi, beaconchainApi, brainDb, - reloadValidatorsCronTask + reloadValidatorsCronTask, + allowedOriginsFromEnv }: { brainConfig: BrainConfig; uiBuildPath: string; @@ -31,6 +32,7 @@ export const getServers = ({ beaconchainApi: BeaconchainApi; brainDb: BrainDataBase; reloadValidatorsCronTask: CronJob; + allowedOriginsFromEnv: string[] | null; }): { uiServer: http.Server; launchpadServer: http.Server; @@ -46,7 +48,8 @@ export const getServers = ({ validatorApi, blockExplorerApi, beaconchainApi, - postgresClient + postgresClient, + allowedOriginsFromEnv }), launchpadServer: startLaunchpadApi({ brainDb, @@ -55,10 +58,12 @@ export const getServers = ({ beaconchainApi, reloadValidatorsCronTask, network: brainConfig.chain.network, - signerUrl: brainConfig.apis.signerUrl + signerUrl: brainConfig.apis.signerUrl, + allowedOriginsFromEnv }), brainApiServer: startBrainApi({ - brainDb + brainDb, + allowedOriginsFromEnv }) }; }; diff --git a/packages/brain/src/modules/apiServers/launchpad/config.ts b/packages/brain/src/modules/apiServers/launchpad/config.ts index 71966a93..32e2fdf7 100644 --- a/packages/brain/src/modules/apiServers/launchpad/config.ts +++ b/packages/brain/src/modules/apiServers/launchpad/config.ts @@ -1,10 +1,8 @@ -export const corsOptions = { - origin: [ - "http://rocketpool-testnet.public.dappnode", - "http://rocketpool.dappnode", - "http://stader-testnet.dappnode", - "http://stader.dappnode", - "http://ui.lido-csm-holesky.dappnode", - "http://ui.lido-csm-mainnet.dappnode" - ] -}; +export const allowedOrigins = [ + "http://rocketpool-testnet.public.dappnode", + "http://rocketpool.dappnode", + "http://stader-testnet.dappnode", + "http://stader.dappnode", + "http://ui.lido-csm-holesky.dappnode", + "http://ui.lido-csm-mainnet.dappnode" +]; diff --git a/packages/brain/src/modules/apiServers/launchpad/startLaunchpadApi.ts b/packages/brain/src/modules/apiServers/launchpad/startLaunchpadApi.ts index 8562848e..7355a636 100644 --- a/packages/brain/src/modules/apiServers/launchpad/startLaunchpadApi.ts +++ b/packages/brain/src/modules/apiServers/launchpad/startLaunchpadApi.ts @@ -3,7 +3,7 @@ import cors from "cors"; import logger from "../../logger/index.js"; import http from "node:http"; import { params } from "../../../params.js"; -import { corsOptions } from "./config.js"; +import { allowedOrigins } from "./config.js"; import { createKeystoresRouter, createFeeRecipientsRouter } from "./routes/index.js"; import { CronJob } from "../../cron/cron.js"; import { BrainDataBase } from "../../db/index.js"; @@ -19,7 +19,8 @@ export function startLaunchpadApi({ reloadValidatorsCronTask, brainDb, network, - signerUrl + signerUrl, + allowedOriginsFromEnv }: { signerApi: Web3SignerApi; validatorApi: ValidatorApi; @@ -28,10 +29,11 @@ export function startLaunchpadApi({ brainDb: BrainDataBase; network: Network; signerUrl: string; + allowedOriginsFromEnv: string[] | null; }): http.Server { const app = express(); app.use(express.json()); - app.use(cors(corsOptions)); + app.use(cors({ origin: allowedOriginsFromEnv ?? allowedOrigins })); app.use(createKeystoresRouter({ reloadValidatorsCronTask, brainDb, network, validatorApi, signerApi, signerUrl })); app.use( diff --git a/packages/brain/src/modules/apiServers/ui/config.ts b/packages/brain/src/modules/apiServers/ui/config.ts new file mode 100644 index 00000000..8aee4d89 --- /dev/null +++ b/packages/brain/src/modules/apiServers/ui/config.ts @@ -0,0 +1,3 @@ +import { BRAIN_UI_DOMAIN, Network } from "@stakingbrain/common"; + +export const allowedOrigins = (network: Network) => ["http://my.dappnode", `http://${BRAIN_UI_DOMAIN(network)}`]; diff --git a/packages/brain/src/modules/apiServers/ui/startUiServer.ts b/packages/brain/src/modules/apiServers/ui/startUiServer.ts index a4d45365..a3eac7fd 100644 --- a/packages/brain/src/modules/apiServers/ui/startUiServer.ts +++ b/packages/brain/src/modules/apiServers/ui/startUiServer.ts @@ -1,4 +1,4 @@ -import { BRAIN_UI_DOMAIN, Network } from "@stakingbrain/common"; +import { Network } from "@stakingbrain/common"; import cors from "cors"; import express from "express"; import path from "path"; @@ -19,6 +19,7 @@ import { ValidatorApi, Web3SignerApi } from "../../apiClients/index.js"; +import { allowedOrigins } from "./config.js"; // Define the type for the RPC request interface RpcRequest { @@ -38,7 +39,8 @@ export function startUiServer({ postgresClient, uiBuildPath, brainConfig, - reloadValidatorsCronTask + reloadValidatorsCronTask, + allowedOriginsFromEnv }: { brainDb: BrainDataBase; blockExplorerApi: BlockExplorerApi; @@ -49,6 +51,7 @@ export function startUiServer({ uiBuildPath: string; brainConfig: BrainConfig; reloadValidatorsCronTask: CronJob; + allowedOriginsFromEnv: string[] | null; }): http.Server { const { network } = brainConfig.chain; // create index.html modified with network @@ -114,10 +117,9 @@ export function startUiServer({ }); // Express - const allowedOrigins = ["http://my.dappnode", `http://${BRAIN_UI_DOMAIN(network)}`]; app.use( cors({ - origin: allowedOrigins + origin: allowedOriginsFromEnv ?? allowedOrigins(network) }) ); app.use(express.json()); diff --git a/packages/brain/src/modules/config/index.ts b/packages/brain/src/modules/config/index.ts index e04700ff..87711262 100644 --- a/packages/brain/src/modules/config/index.ts +++ b/packages/brain/src/modules/config/index.ts @@ -6,7 +6,7 @@ import { getValidatorToken } from "./getValidatorToken.js"; import { getTlsCert } from "./getTlsCert.js"; export const brainConfig = (): BrainConfig => { - const { network, executionClient, consensusClient, isMevBoostSet } = loadEnvs(); + const { network, executionClient, consensusClient, isMevBoostSet, cors } = loadEnvs(); // Determine the validator URL based on the consensus client and network. // All this logic is needed because Teku has a TLS certificate that points to the old @@ -44,7 +44,8 @@ export const brainConfig = (): BrainConfig => { postgresUrl: getPostgresUrl(network), token: getValidatorToken(consensusClient), host: network === "mainnet" ? `brain.web3signer.dappnode` : `brain.web3signer-${network}.dappnode`, - tlsCert: getTlsCert(consensusClient, network) // To avoid Teku edge case it is necessary to update TLS certificate in both: validator and brain + tlsCert: getTlsCert(consensusClient, network), // To avoid Teku edge case it is necessary to update TLS certificate in both: validator and brain + cors } }; }; diff --git a/packages/brain/src/modules/config/loadEnvs.ts b/packages/brain/src/modules/config/loadEnvs.ts index a9620614..3bbd0d01 100644 --- a/packages/brain/src/modules/config/loadEnvs.ts +++ b/packages/brain/src/modules/config/loadEnvs.ts @@ -5,6 +5,7 @@ export function loadEnvs(): { executionClient: ExecutionClient; consensusClient: ConsensusClient; isMevBoostSet: boolean; + cors: string[] | null; } { const network = getNetwork(); @@ -17,7 +18,8 @@ export function loadEnvs(): { network: network as Network, executionClient, consensusClient, - isMevBoostSet + isMevBoostSet, + cors: process.env.CORS ? process.env.CORS.split(",") : null }; } diff --git a/packages/brain/src/modules/config/types.ts b/packages/brain/src/modules/config/types.ts index 732e1737..e71ed21c 100644 --- a/packages/brain/src/modules/config/types.ts +++ b/packages/brain/src/modules/config/types.ts @@ -17,6 +17,7 @@ export interface ApisConfig { token: string; tlsCert: Buffer | null; host: string; + cors: string[] | null; } export interface ChainConfig {