read configs from env
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1 @@
|
|||||||
summerizer.py
|
summerizer.py
|
||||||
.env
|
|
||||||
36
BuildConfig.sh
Normal file
36
BuildConfig.sh
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
rm -f /app/config.js;
|
||||||
|
if [ -z "$BACKEND_HOST" ]; then
|
||||||
|
BACKEND_HOST="http://localhost:5000"
|
||||||
|
fi
|
||||||
|
if [ -z "$FRONTEND_HOST" ]; then
|
||||||
|
FRONTEND_HOST="http://localhost:3000"
|
||||||
|
fi
|
||||||
|
if [ -z "$KC_CLIENT_ID" ]; then
|
||||||
|
KC_CLIENT_ID="labdev"
|
||||||
|
fi
|
||||||
|
if [ -z "$KC_HOST" ]; then
|
||||||
|
KC_HOST="https://login.hangman-lab.top"
|
||||||
|
fi
|
||||||
|
if [ -z "$KC_REALM" ]; then
|
||||||
|
KC_REALM="Hangman-Lab"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /app/src
|
||||||
|
|
||||||
|
echo "
|
||||||
|
const config = {
|
||||||
|
BACKEND_HOST: \"${BACKEND_HOST}\",
|
||||||
|
FRONTEND_HOST: \"${FRONTEND_HOST}\",
|
||||||
|
KC_CLIENT_ID: \"${KC_CLIENT_ID}\",
|
||||||
|
OIDC_CONFIG: {
|
||||||
|
authority: \"${KC_HOST}/realms/${KC_REALM}\",
|
||||||
|
client_id: \"${KC_CLIENT_ID}\",
|
||||||
|
redirect_uri: \"${FRONTEND_HOST}/callback\",
|
||||||
|
post_logout_redirect_uri: \"${FRONTEND_HOST}\",
|
||||||
|
response_type: \"code\",
|
||||||
|
scope: \"openid profile email roles\",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default config;
|
||||||
|
" > /app/src/config.js;
|
||||||
@@ -6,8 +6,11 @@ COPY package*.json ./
|
|||||||
RUN npm install
|
RUN npm install
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
COPY BuildConfig.sh /app/BuildConfig.sh
|
||||||
|
RUN chmod +x /app/BuildConfig.sh
|
||||||
|
RUN /app/BuildConfig.sh >&1
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
CMD ["npm", "start"]
|
CMD ["/bin/bash", "-c", "/app/BuildConfig.sh && npm start"]
|
||||||
@@ -6,9 +6,10 @@ import MarkdownContent from "./components/MarkdownContent";
|
|||||||
import MarkdownEditor from "./components/Markdowns/MarkdownEditor";
|
import MarkdownEditor from "./components/Markdowns/MarkdownEditor";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import Callback from "./Callback";
|
import Callback from "./Callback";
|
||||||
import {config} from "./confs/appConfig";
|
import config from "./config";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
console.log(config)
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
<div className="app-container">
|
<div className="app-container">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, {createContext, useEffect, useMemo, useState} from "react";
|
import React, {createContext, useEffect, useMemo, useState} from "react";
|
||||||
import { UserManager } from "oidc-client-ts";
|
import { UserManager } from "oidc-client-ts";
|
||||||
import {appConfig} from "./confs/appConfig";
|
import config from "./config";
|
||||||
|
|
||||||
|
|
||||||
export const AuthContext = createContext({
|
export const AuthContext = createContext({
|
||||||
@@ -14,10 +14,7 @@ const AuthProvider = ({ children }) => {
|
|||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState(null);
|
||||||
const [roles, setRoles] = useState([]);
|
const [roles, setRoles] = useState([]);
|
||||||
const userManager =
|
const userManager =
|
||||||
useMemo(() => new UserManager(appConfig.oidcConfig), []);
|
useMemo(() => new UserManager(config.OIDC_CONFIG), []);
|
||||||
|
|
||||||
|
|
||||||
//new UserManager(appConfig.oidcConfig);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
userManager.getUser()
|
userManager.getUser()
|
||||||
@@ -25,7 +22,7 @@ const AuthProvider = ({ children }) => {
|
|||||||
if (user && !user.expired) {
|
if (user && !user.expired) {
|
||||||
setUser(user);
|
setUser(user);
|
||||||
localStorage.setItem("accessToken", user.access_token);
|
localStorage.setItem("accessToken", user.access_token);
|
||||||
const clientRoles = user?.profile?.resource_access?.[appConfig.kc_client_id]?.roles || [];
|
const clientRoles = user?.profile?.resource_access?.[config.KC_CLIENT_ID]?.roles || [];
|
||||||
setRoles(clientRoles);
|
setRoles(clientRoles);
|
||||||
} else if (user && user.expired) {
|
} else if (user && user.expired) {
|
||||||
userManager
|
userManager
|
||||||
@@ -34,7 +31,7 @@ const AuthProvider = ({ children }) => {
|
|||||||
setUser(newUser);
|
setUser(newUser);
|
||||||
localStorage.setItem("accessToken", newUser.access_token);
|
localStorage.setItem("accessToken", newUser.access_token);
|
||||||
const clientRoles =
|
const clientRoles =
|
||||||
newUser?.profile?.resource_access?.[appConfig.kc_client_id]?.roles || [];
|
newUser?.profile?.resource_access?.[config.KC_CLIENT_ID]?.roles || [];
|
||||||
setRoles(clientRoles);
|
setRoles(clientRoles);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@@ -49,7 +46,7 @@ const AuthProvider = ({ children }) => {
|
|||||||
.signinRedirect()
|
.signinRedirect()
|
||||||
.catch(
|
.catch(
|
||||||
(err) => {
|
(err) => {
|
||||||
console.log(appConfig);
|
console.log(config);
|
||||||
console.log(err);
|
console.log(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { UserManager } from "oidc-client-ts";
|
import { UserManager } from "oidc-client-ts";
|
||||||
import {appConfig} from "./confs/appConfig";
|
import config from "./config";
|
||||||
|
|
||||||
|
|
||||||
const Callback = () => {
|
const Callback = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const userManager = new UserManager(appConfig.oidcConfig);
|
const userManager = new UserManager(config.OIDC_CONFIG);
|
||||||
userManager.signinRedirectCallback().then(() => {
|
userManager.signinRedirectCallback()
|
||||||
window.location.href = "/";
|
.then(() => {
|
||||||
});
|
window.location.href = "/";
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <div>Logging in...</div>;
|
return <div>Logging in...</div>;
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 1px solid #dcdcdc;
|
border: 1px solid #dcdcdc;
|
||||||
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
height: 70vh !important;
|
||||||
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-editor-form .input:focus,
|
.markdown-editor-form .input:focus,
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ import rehypeKatex from "rehype-katex";
|
|||||||
import rehypeRaw from "rehype-raw";
|
import rehypeRaw from "rehype-raw";
|
||||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism";
|
import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism";
|
||||||
import "katex/dist/katex.min.css"; // LaTeX 样式
|
import "katex/dist/katex.min.css";
|
||||||
import "./MarkdownEditor.css";
|
import "./MarkdownEditor.css";
|
||||||
|
import config from "../../config";
|
||||||
|
|
||||||
const MarkdownEditor = () => {
|
const MarkdownEditor = () => {
|
||||||
const { roles } = useContext(AuthContext);
|
const { roles } = useContext(AuthContext);
|
||||||
@@ -34,7 +35,7 @@ const MarkdownEditor = () => {
|
|||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
const url = id ? `/api/markdown/${id}` : "/api/markdown";
|
const url = id ? `${config.BACKEND_HOST}/api/markdown/${id}` : `${config.BACKEND_HOST}/api/markdown`;
|
||||||
const method = id ? "PUT" : "POST";
|
const method = id ? "PUT" : "POST";
|
||||||
fetch(url, {
|
fetch(url, {
|
||||||
method,
|
method,
|
||||||
@@ -102,6 +103,7 @@ const MarkdownEditor = () => {
|
|||||||
<label className="label">Content</label>
|
<label className="label">Content</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<textarea
|
<textarea
|
||||||
|
style={{ height: "70vh" }}
|
||||||
className="textarea"
|
className="textarea"
|
||||||
placeholder="Enter Markdown content"
|
placeholder="Enter Markdown content"
|
||||||
value={content}
|
value={content}
|
||||||
@@ -128,7 +130,7 @@ const MarkdownEditor = () => {
|
|||||||
{/* Preview Column */}
|
{/* Preview Column */}
|
||||||
<div className="column is-half">
|
<div className="column is-half">
|
||||||
<h3 className="subtitle is-5">Preview</h3>
|
<h3 className="subtitle is-5">Preview</h3>
|
||||||
<div className="content markdown-preview">
|
<div className="content markdown-preview" style={{ height: "70vh" }}>
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
children={content}
|
children={content}
|
||||||
remarkPlugins={[remarkMath]}
|
remarkPlugins={[remarkMath]}
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ import { Link } from "react-router-dom";
|
|||||||
import "./SideNavigation.css";
|
import "./SideNavigation.css";
|
||||||
import {fetchWithCache} from "../../utils/fetchWithCache";
|
import {fetchWithCache} from "../../utils/fetchWithCache";
|
||||||
import PermissionGuard from "../PermissionGuard";
|
import PermissionGuard from "../PermissionGuard";
|
||||||
|
import config from "../../config";
|
||||||
|
|
||||||
const SideNavigation = () => {
|
const SideNavigation = () => {
|
||||||
const [markdowns, setMarkdowns] = useState([]);
|
const [markdowns, setMarkdowns] = useState([]);
|
||||||
const [tree, setTree] = useState(null);
|
const [tree, setTree] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchWithCache("http://127.0.0.1:5000/api/markdown/")
|
fetchWithCache(`${config.BACKEND_HOST}/api/markdown/`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setMarkdowns(data);
|
setMarkdowns(data);
|
||||||
setTree(buildTree(data));
|
setTree(buildTree(data));
|
||||||
@@ -51,7 +52,7 @@ const SideNavigation = () => {
|
|||||||
if (value.markdown) {
|
if (value.markdown) {
|
||||||
return (
|
return (
|
||||||
<li key={value.markdown.id}>
|
<li key={value.markdown.id}>
|
||||||
<Link to={`http://127.0.0.1:5000/markdown/${value.markdown.id}`}>
|
<Link to={`${config.BACKEND_HOST}/markdown/${value.markdown.id}`}>
|
||||||
{value.markdown.title}
|
{value.markdown.title}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
10
src/config.js
Normal file
10
src/config.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
const config = {
|
||||||
|
BACKEND_HOST: null,
|
||||||
|
FRONTEND_HOST: null,
|
||||||
|
KC_CLIENT_ID: null,
|
||||||
|
OIDC_CONFIG: {},
|
||||||
|
TEST_PASS1: null,
|
||||||
|
TEST_PASS2: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
const appConfig = {
|
|
||||||
serverHost : null,
|
|
||||||
kc_client_id: null,
|
|
||||||
oidcConfig : null
|
|
||||||
};
|
|
||||||
|
|
||||||
const config = async () => {
|
|
||||||
await fetch("http://127.0.0.1:5000/api/config/server_host")
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => appConfig.serverHost = data['value'])
|
|
||||||
.catch((err) => console.error(err));
|
|
||||||
await fetch("http://127.0.0.1:5000/api/config/kc_client_id")
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => appConfig["kc_client_id"] = data["value"])
|
|
||||||
.catch((err) => console.error(err));
|
|
||||||
appConfig.oidcConfig = {
|
|
||||||
authority: "https://login.hangman-lab.top/realms/Hangman-Lab",
|
|
||||||
client_id: appConfig.kc_client_id,
|
|
||||||
redirect_uri: `${appConfig.serverHost}/callback`,
|
|
||||||
post_logout_redirect_uri: appConfig.serverHost,
|
|
||||||
response_type: "code",
|
|
||||||
scope: "openid profile email roles",
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export {appConfig, config};
|
|
||||||
17
src/index.js
17
src/index.js
@@ -2,21 +2,16 @@ import React from "react";
|
|||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import AuthProvider from "./AuthProvider";
|
import AuthProvider from "./AuthProvider";
|
||||||
import {config} from "./confs/appConfig";
|
|
||||||
import "bulma/css/bulma.min.css";
|
import "bulma/css/bulma.min.css";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//ReactDOM.render(<App />, document.getElementById("root"));
|
//ReactDOM.render(<App />, document.getElementById("root"));
|
||||||
|
|
||||||
const initializeApp = async () => {
|
|
||||||
await config();
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
|
||||||
root.render(
|
|
||||||
<AuthProvider>
|
|
||||||
<App />
|
|
||||||
</AuthProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeApp();
|
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||||
|
root.render(
|
||||||
|
<AuthProvider>
|
||||||
|
<App />
|
||||||
|
</AuthProvider>
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user