diff --git a/.env.development b/.env.development new file mode 100644 index 000000000..b884c309b --- /dev/null +++ b/.env.development @@ -0,0 +1,6 @@ +# Development API Configuration +REACT_APP_API_URL=https://api.policyengine.org +REACT_APP_API_AUDIENCE=https://api.policyengine.org/ + +# Development mode flag +REACT_APP_DEBUG=true \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..c1e428c06 --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +# API Configuration +REACT_APP_API_URL=https://api.policyengine.org +REACT_APP_API_AUDIENCE=https://api.policyengine.org/ + +# Development mode +REACT_APP_DEBUG=true + +# For local development, uncomment these and use appropriate URLs +# REACT_APP_API_URL=http://localhost:5000 +# REACT_APP_API_AUDIENCE=http://localhost:5000/ \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 000000000..def417866 --- /dev/null +++ b/.env.production @@ -0,0 +1,6 @@ +# Production API Configuration +REACT_APP_API_URL=https://api.policyengine.org +REACT_APP_API_AUDIENCE=https://api.policyengine.org/ + +# Debug mode should be off in production +REACT_APP_DEBUG=false \ No newline at end of file diff --git a/README.md b/README.md index 08bf84a5c..b88167821 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,30 @@ We recommend that you use the latest Node version 19. To easily manage your node nvm install 19 && nvm use 19 ``` +# Environment Variables + +The application uses environment variables to configure API endpoints and other settings. These are defined in the following files: + +- `.env.development` - Used during local development +- `.env.production` - Used in production builds + +You can customize your local development setup by modifying `.env.development` or creating a `.env.local` file which will override other environment files. + +Available environment variables: + +| Variable | Description | Default | +|----------|-------------|---------| +| REACT_APP_API_URL | Base URL for API requests | https://api.policyengine.org | +| REACT_APP_API_AUDIENCE | Auth0 audience for API | https://api.policyengine.org/ | +| REACT_APP_DEBUG | Enable debug mode | true (dev) / false (prod) | + +For local development with a backend running on your machine, you might want to use: +``` +REACT_APP_API_URL=http://localhost:5000 +REACT_APP_API_AUDIENCE=http://localhost:5000/ +REACT_APP_DEBUG=true +``` + # Contributing ## Choosing an Issue diff --git a/package-lock.json b/package-lock.json index b000f6219..8c73112c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "moment": "^2.30.1", "openai": "^4.91.0", "plotly.js": "^2.35.3", + "policyengine-app": "file:", "react": "^18.3.1", "react-bootstrap": "^2.10.9", "react-detect-print": "^0.1.2", @@ -19801,6 +19802,10 @@ "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==" }, + "node_modules/policyengine-app": { + "resolved": "", + "link": true + }, "node_modules/polybooljs": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/polybooljs/-/polybooljs-1.2.2.tgz", diff --git a/package.json b/package.json index e8bd84d08..62bb9828c 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "moment": "^2.30.1", "openai": "^4.91.0", "plotly.js": "^2.35.3", + "policyengine-app": "file:", "react": "^18.3.1", "react-bootstrap": "^2.10.9", "react-detect-print": "^0.1.2", diff --git a/src/api/call.js b/src/api/call.js index 8bf04d78b..280de7c8f 100644 --- a/src/api/call.js +++ b/src/api/call.js @@ -1,10 +1,9 @@ import { useCallback } from "react"; -import { buildParameterTree } from "./parameters"; -import { buildVariableTree, getTreeLeavesInOrder } from "./variables"; +import { API_URL } from "../config"; import { wrappedJsonStringify, wrappedResponseJson } from "../data/wrappedJson"; import { useAuthenticatedFetch } from "../hooks/useAuthenticatedFetch"; - -const POLICYENGINE_API = "https://api.policyengine.org"; +import { buildParameterTree } from "./parameters"; +import { buildVariableTree, getTreeLeavesInOrder } from "./variables"; /** * returns an api call function that can be used to make requests @@ -47,7 +46,7 @@ export function apiCall( secondAttempt = false, fetchMethod = fetch, ) { - return fetchMethod(POLICYENGINE_API + path, { + return fetchMethod(API_URL + path, { method: method || (body ? "POST" : "GET"), headers: { "Content-Type": "application/json", diff --git a/src/auth/Auth0ProviderWithNavigate.jsx b/src/auth/Auth0ProviderWithNavigate.jsx index 9674df918..e0762c7bd 100644 --- a/src/auth/Auth0ProviderWithNavigate.jsx +++ b/src/auth/Auth0ProviderWithNavigate.jsx @@ -1,6 +1,6 @@ -import { useNavigate } from "react-router-dom"; import { Auth0Provider } from "@auth0/auth0-react"; -import { AUTH0_CLIENT_ID, AUTH0_DOMAIN } from "./authUtils"; +import { useNavigate } from "react-router-dom"; +import { API_AUDIENCE, AUTH0_CLIENT_ID, AUTH0_DOMAIN, AUTH0_REDIRECT_URI } from "../config"; export default function Auth0ProviderWithNavigate({ children }) { const navigate = useNavigate(); @@ -8,9 +8,7 @@ export default function Auth0ProviderWithNavigate({ children }) { const domain = AUTH0_DOMAIN; const clientId = AUTH0_CLIENT_ID; - const redirectUri = process.env.REACT_APP_DEBUG - ? "http://localhost:3000/callback" - : "https://policyengine.org/callback"; + const redirectUri = AUTH0_REDIRECT_URI; const onRedirectCallback = (appState) => { navigate(appState?.returnTo || window.location.pathname); @@ -26,7 +24,7 @@ export default function Auth0ProviderWithNavigate({ children }) { clientId={clientId} authorizationParams={{ redirect_uri: redirectUri, - audience: "https://api.policyengine.org/", + audience: API_AUDIENCE, }} onRedirectCallback={onRedirectCallback} useRefreshTokens={true} diff --git a/src/auth/authUtils.js b/src/auth/authUtils.js index 8ed2e1a46..296956de9 100644 --- a/src/auth/authUtils.js +++ b/src/auth/authUtils.js @@ -1,6 +1,3 @@ -// The below are two public values vital to auth0 local setup -export const AUTH0_DOMAIN = "policyengine.uk.auth0.com"; -export const AUTH0_CLIENT_ID = "jbAXjeFRxGpGRxkedjt2wRLHJd26bwDS"; /** * Provide login options for use with auth0 diff --git a/src/config/index.js b/src/config/index.js new file mode 100644 index 000000000..a910ad128 --- /dev/null +++ b/src/config/index.js @@ -0,0 +1,17 @@ +/** + * Configuration values for the application + * These can be overridden by environment variables + */ + +// API URLs +export const API_URL = process.env.REACT_APP_API_URL || "https://api.policyengine.org"; +export const API_AUDIENCE = process.env.REACT_APP_API_AUDIENCE || "https://api.policyengine.org/"; + +// Auth configuration (moved from authUtils.js for centralization) +export const AUTH0_DOMAIN = "policyengine.uk.auth0.com"; +export const AUTH0_CLIENT_ID = "jbAXjeFRxGpGRxkedjt2wRLHJd26bwDS"; + +// Redirect URL for Auth0 +export const AUTH0_REDIRECT_URI = process.env.REACT_APP_DEBUG + ? "http://localhost:3000/callback" + : "https://policyengine.org/callback"; \ No newline at end of file diff --git a/src/hooks/useAuthenticatedFetch.js b/src/hooks/useAuthenticatedFetch.js index 515b46098..6dc1d82d5 100644 --- a/src/hooks/useAuthenticatedFetch.js +++ b/src/hooks/useAuthenticatedFetch.js @@ -1,5 +1,6 @@ import { useAuth0 } from "@auth0/auth0-react"; import { useCallback } from "react"; +import { API_AUDIENCE } from "../config"; /** * Get an 'authenticatedFetch' function which, if the user is logged in, @@ -18,7 +19,7 @@ export function useAuthenticatedFetch() { try { //as per https://auth0.com/docs/quickstart/spa/react/02-calling-an-api const accessToken = await getAccessTokenSilently({ - audience: "https://api.policyengine.org/", + audience: API_AUDIENCE, }); headers["Authorization"] = `Bearer ${accessToken}`; } catch (error) {