Skip to content

Commit

Permalink
Json config to envvars (#10)
Browse files Browse the repository at this point in the history
* fix - upgrade package, add env-config file

* fix - add scripts, entrypoint, env conf

* fix - adapt components to env imports, remove config from appcontext

* fix - finalize PR, remove useless files and config

* fix - adapt dockerfile

* fix - adapt dockerfile

* fix - finalize PR, remove useless files and config

* fix - remove useless oidctrusteddomains conf
  • Loading branch information
EricThuaud authored Oct 20, 2023
1 parent 058de12 commit 01d16a6
Show file tree
Hide file tree
Showing 22 changed files with 87 additions and 123 deletions.
7 changes: 7 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# REACT_APP_AUTH_TYPE: oidc / none, default: none
REACT_APP_AUTH_TYPE=NONE
REACT_APP_CLIENT_ID=myClient
REACT_APP_AUTHORITY=https://auth.server
REACT_APP_PORTAIL_URL=https://localhost:3000
REACT_APP_MANAGEMENT_API_BASE_URL=https://localhost:3001
REACT_APP_REALM=myRealm
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

/public/OidcTrustedDomains.js
15 changes: 6 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
FROM nginx
RUN rm -rf /usr/share/nginx/html/*

ADD build /usr/share/nginx/html
RUN rm etc/nginx/conf.d/default.conf
COPY nginx.conf etc/nginx/conf.d/

# Copy .env file and shell script to container
WORKDIR /usr/share/nginx/html
COPY ./scripts/env.sh .
COPY ./scripts/.env .

# Make shell script executable and prevent windows encoding
RUN sed -i -e 's/\r$//' env.sh && sed -i -e 's/\r$//' .env && chmod +x env.sh
COPY entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]

# Start Nginx server
CMD ["/bin/bash", "-c", "/usr/share/nginx/html/env.sh && nginx -g \"daemon off;\""]
CMD ["nginx", "-g", "daemon off;"]
6 changes: 0 additions & 6 deletions configuration/configuration.json

This file was deleted.

8 changes: 0 additions & 8 deletions configuration/keycloak.json

This file was deleted.

8 changes: 8 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
echo "self._env_['REACT_APP_AUTH_TYPE'] = '$REACT_APP_AUTH_TYPE';" >> /usr/share/nginx/html/env-config.js
echo "self._env_['REACT_APP_CLIENT_ID'] = '$REACT_APP_CLIENT_ID';" >> /usr/share/nginx/html/env-config.js
echo "self._env_['REACT_APP_AUTHORITY'] = '$REACT_APP_AUTHORITY';" >> /usr/share/nginx/html/env-config.js
echo "self._env_['REACT_APP_PORTAIL_URL'] = '$REACT_APP_PORTAIL_URL';" >> /usr/share/nginx/html/env-config.js
echo "self._env_['REACT_APP_MANAGEMENT_API_BASE_URL'] = '$REACT_APP_MANAGEMENT_API_BASE_URL';" >> /usr/share/nginx/html/env-config.js
echo "self._env_['REACT_APP_REALM'] = '$REACT_APP_REALM';" >> /usr/share/nginx/html/env-config.js
exec "$@"
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "coleman-my-surveys",
"version": "0.2.14",
"version": "0.2.15",
"private": true,
"dependencies": {
"@emotion/react": "^11.9.0",
Expand Down
5 changes: 0 additions & 5 deletions public/configuration.json

This file was deleted.

2 changes: 2 additions & 0 deletions public/env-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable no-restricted-globals */
if (!self._env_) self._env_ = {};
8 changes: 0 additions & 8 deletions public/keycloak.json

This file was deleted.

6 changes: 0 additions & 6 deletions scripts/.env

This file was deleted.

24 changes: 0 additions & 24 deletions scripts/env.sh

This file was deleted.

13 changes: 13 additions & 0 deletions scripts/generate-entrypoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const fs = require("fs");

fs.readFile(".env", "utf8", function (_, contents) {
const content = contents
.split("\n")
.filter(line => !line.startsWith("#"))
.map(line => line.split("="))
.filter(data => data.length === 2)
.map(([key]) => `echo "self._env_['${key}'] = '$${key}';" >> /usr/share/nginx/html/env-config.js`);

const fullFile = ["#!/bin/sh", ...content, 'exec "$@"'].join("\n");
fs.writeFileSync("entrypoint.sh", fullFile, "utf8");
});
38 changes: 10 additions & 28 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Alert, Snackbar } from "@mui/material";
import { getConfiguration } from "core/configuration";
import React, { createContext, useEffect, useMemo, useState } from "react";
import React, { createContext, useMemo, useState } from "react";
import "./App.css";
import AuthProvider from "./ui/context/auth/provider/component";
import { Router } from "./ui/router";
Expand All @@ -9,7 +8,6 @@ import { LoaderSimple } from "./ui/shared/loader";
export const AppContext = createContext();

const App = () => {
const [configuration, setConfiguration] = useState(null);
const [isLoading, setLoading] = useState(false);
const [notif, setNotif] = useState({ open: false, severity: "info", message: "" });
const packageInfo = require("../package.json");
Expand All @@ -19,18 +17,6 @@ const App = () => {
setNotif({ open: true, message, severity });
};

useEffect(() => {
if (!configuration) {
setLoading(true);
const loadConfiguration = async () => {
const configurationResponse = await getConfiguration();
setLoading(false);
setConfiguration(configurationResponse);
};
loadConfiguration();
}
}, [configuration]);

const handleClose = (event, reason) => {
if (reason === "clickaway") {
return;
Expand All @@ -39,22 +25,18 @@ const App = () => {
setNotif(oldNotif => ({ ...oldNotif, open: false }));
};

const context = useMemo(
() => ({ ...configuration, appVersion, setLoading, openNotif }),
[configuration],
);
const context = useMemo(() => ({ appVersion, setLoading, openNotif }), []);

return (
<>
{configuration && (
<AppContext.Provider value={context}>
<AuthProvider authType={configuration.authType}>
<React.StrictMode>
<Router />
</React.StrictMode>
</AuthProvider>
</AppContext.Provider>
)}
<AppContext.Provider value={context}>
<AuthProvider>
<React.StrictMode>
<Router />
</React.StrictMode>
</AuthProvider>
</AppContext.Provider>

{isLoading && <LoaderSimple />}
<Snackbar open={notif.open} autoHideDuration={6000} onClose={handleClose}>
<Alert onClose={handleClose} severity={notif.severity} sx={{ width: "100%" }}>
Expand Down
1 change: 0 additions & 1 deletion src/core/configuration/env.js

This file was deleted.

13 changes: 0 additions & 13 deletions src/core/configuration/get-configuration.js

This file was deleted.

2 changes: 0 additions & 2 deletions src/core/configuration/index.js

This file was deleted.

4 changes: 2 additions & 2 deletions src/core/hooks/api.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useContext } from "react";
import { AppContext } from "App";
import { AuthContext } from "ui/context/auth/provider";
import { API } from "core/api";
import { useConstCallback } from "./useConstCallback";
import { environment } from "utils/read-env-vars";

export const useAPI = () => {
const oidcClient = useContext(AuthContext);
const { apiUrl } = useContext(AppContext);
const { API_URL: apiUrl } = environment;

const getFirstContacts = useConstCallback(() => API.getContacts(apiUrl)(oidcClient?.accessToken));

Expand Down
15 changes: 8 additions & 7 deletions src/ui/context/auth/provider/component.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import { getOidc } from "core/configuration";
import { NONE, OIDC } from "core/constants";
import { listenActivity } from "core/events";
import { createKeycloakOidcClient } from "core/keycloak";
import React, { useEffect, useMemo, useState } from "react";
import { LoaderSimple } from "ui/shared/loader";
import { NoAuthLogin } from "./noAuth";
import { environment, oidcConf } from "utils/read-env-vars";

export const AuthContext = React.createContext();

const { AUTH_TYPE: authType } = environment;
const { authority, realm, client_id } = oidcConf;

const dummyOidcClient = {
isUserLoggedIn: false,
};

const AuthProvider = ({ authType, children }) => {
const AuthProvider = ({ children }) => {
const [oidcClient, setOidcClient] = useState(null);

useEffect(() => {
const loadOidcConf = async () => {
const oidcConf = await getOidc();

const oidcClientKC = await createKeycloakOidcClient({
url: oidcConf["auth-server-url"],
realm: oidcConf["realm"],
clientId: oidcConf["resource"],
url: authority,
realm: realm,
clientId: client_id,
evtUserActivity: listenActivity,
});
return oidcClientKC;
Expand Down
4 changes: 3 additions & 1 deletion src/ui/context/auth/provider/noAuth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import { ERROR_SEVERITY } from "core/constants";
import { buttonDictionary } from "i18n";
import "./noAuth.css";
import { API } from "core/api";
import { environment } from "utils/read-env-vars";

export const NoAuthLogin = ({ setOidcClient }) => {
const { apiUrl, portailUrl, setLoading, openNotif } = useContext(AppContext);
const { setLoading, openNotif } = useContext(AppContext);
const { API_URL: apiUrl, PORTAIL_URL: portailUrl } = environment;
const [contacts, setContacts] = useState([]);
const [selected, setSelected] = useState("");
const [idSelected, setIdSelected] = useState("");
Expand Down
4 changes: 2 additions & 2 deletions src/ui/shared/Header/index.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { AccountCircle, ContactSupport, Logout } from "@mui/icons-material";
import { Button, Divider, ListItem, ListItemIcon, Menu, MenuItem, Tooltip } from "@mui/material";
import { AuthContext } from "ui/context/auth/provider";
import { AppContext } from "App";
import { UserAccountContext } from "ui/context/UserAccount";
import { useContext, useState } from "react";
import Link from "@mui/material/Link";
import { defaultDictionary, buttonDictionary } from "i18n";
import "./header.css";
import { environment } from "utils/read-env-vars";

export const Header = () => {
const { logout } = useContext(AuthContext);
const { portailUrl } = useContext(AppContext);
const { PORTAIL_URL: portailUrl } = environment;
const { user } = useContext(UserAccountContext);
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
Expand Down
23 changes: 23 additions & 0 deletions src/utils/read-env-vars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* This function reads environment variables in the order: (If a value is found, it stops.)
* - variables defined inside object window._env_ (env variable injected by environnment, docker)
* @param varName : the variable name
* @returns the value of variable name
*/
export const getEnvVar = varName => {
// eslint-disable-next-line no-restricted-globals
return self?._env_?.[varName] || process.env[varName] || "";
};

export const environment = {
API_URL: getEnvVar("REACT_APP_MANAGEMENT_API_BASE_URL"),
AUTH_TYPE: getEnvVar("REACT_APP_AUTH_TYPE") || "NONE",
PORTAIL_URL: getEnvVar("REACT_APP_PORTAIL_URL") || `${window.location.origin}`,
};

export const oidcConf = {
client_id: getEnvVar("REACT_APP_CLIENT_ID"),
authority: getEnvVar("REACT_APP_AUTHORITY"),
realm: getEnvVar("REACT_APP_REALM"),
scope: "openid profile email offline_access",
};

0 comments on commit 01d16a6

Please sign in to comment.