// Copyright 2021 The Casdoor Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import React, {Component} from "react"; import "./App.less"; import {Helmet} from "react-helmet"; import * as Setting from "./Setting"; import {BarsOutlined, DownOutlined, LogoutOutlined, SettingOutlined} from "@ant-design/icons"; import {Avatar, Button, Card, ConfigProvider, Drawer, Dropdown, FloatButton, Layout, Menu, Result} from "antd"; import {Link, Redirect, Route, Switch, withRouter} from "react-router-dom"; import OrganizationListPage from "./OrganizationListPage"; import OrganizationEditPage from "./OrganizationEditPage"; import UserListPage from "./UserListPage"; import UserEditPage from "./UserEditPage"; import RoleListPage from "./RoleListPage"; import RoleEditPage from "./RoleEditPage"; import PermissionListPage from "./PermissionListPage"; import PermissionEditPage from "./PermissionEditPage"; import ProviderListPage from "./ProviderListPage"; import ProviderEditPage from "./ProviderEditPage"; import ApplicationListPage from "./ApplicationListPage"; import ApplicationEditPage from "./ApplicationEditPage"; import ResourceListPage from "./ResourceListPage"; import LdapEditPage from "./LdapEditPage"; import LdapSyncPage from "./LdapSyncPage"; import TokenListPage from "./TokenListPage"; import TokenEditPage from "./TokenEditPage"; import RecordListPage from "./RecordListPage"; import WebhookListPage from "./WebhookListPage"; import WebhookEditPage from "./WebhookEditPage"; import SyncerListPage from "./SyncerListPage"; import SyncerEditPage from "./SyncerEditPage"; import CertListPage from "./CertListPage"; import CertEditPage from "./CertEditPage"; import ProductListPage from "./ProductListPage"; import ProductEditPage from "./ProductEditPage"; import ProductBuyPage from "./ProductBuyPage"; import PaymentListPage from "./PaymentListPage"; import PaymentEditPage from "./PaymentEditPage"; import PaymentResultPage from "./PaymentResultPage"; import AccountPage from "./account/AccountPage"; import HomePage from "./basic/HomePage"; import CustomGithubCorner from "./CustomGithubCorner"; import * as Conf from "./Conf"; import * as Auth from "./auth/Auth"; import EntryPage from "./EntryPage"; import ResultPage from "./auth/ResultPage"; import * as AuthBackend from "./auth/AuthBackend"; import AuthCallback from "./auth/AuthCallback"; import SelectLanguageBox from "./SelectLanguageBox"; import i18next from "i18next"; import OdicDiscoveryPage from "./auth/OidcDiscoveryPage"; import SamlCallback from "./auth/SamlCallback"; import ModelListPage from "./ModelListPage"; import ModelEditPage from "./ModelEditPage"; import SystemInfo from "./SystemInfo"; import AdapterListPage from "./AdapterListPage"; import AdapterEditPage from "./AdapterEditPage"; import {withTranslation} from "react-i18next"; import SelectThemeBox from "./SelectThemeBox"; import SessionListPage from "./SessionListPage"; const {Header, Footer, Content} = Layout; class App extends Component { constructor(props) { super(props); this.state = { classes: props, selectedMenuKey: 0, account: undefined, uri: null, menuVisible: false, themeAlgorithm: ["default"], themeData: Setting.ThemeDefault, }; Setting.initServerUrl(); Auth.initAuthWithConfig({ serverUrl: Setting.ServerUrl, appName: "app-built-in", // the application name of Casdoor itself, do not change it }); } UNSAFE_componentWillMount() { this.updateMenuKey(); this.getAccount(); } componentDidUpdate() { // eslint-disable-next-line no-restricted-globals const uri = location.pathname; if (this.state.uri !== uri) { this.updateMenuKey(); } } updateMenuKey() { // eslint-disable-next-line no-restricted-globals const uri = location.pathname; this.setState({ uri: uri, }); if (uri === "/") { this.setState({selectedMenuKey: "/"}); } else if (uri.includes("/organizations")) { this.setState({selectedMenuKey: "/organizations"}); } else if (uri.includes("/users")) { this.setState({selectedMenuKey: "/users"}); } else if (uri.includes("/roles")) { this.setState({selectedMenuKey: "/roles"}); } else if (uri.includes("/permissions")) { this.setState({selectedMenuKey: "/permissions"}); } else if (uri.includes("/models")) { this.setState({selectedMenuKey: "/models"}); } else if (uri.includes("/adapters")) { this.setState({selectedMenuKey: "/adapters"}); } else if (uri.includes("/providers")) { this.setState({selectedMenuKey: "/providers"}); } else if (uri.includes("/applications")) { this.setState({selectedMenuKey: "/applications"}); } else if (uri.includes("/resources")) { this.setState({selectedMenuKey: "/resources"}); } else if (uri.includes("/tokens")) { this.setState({selectedMenuKey: "/tokens"}); } else if (uri.includes("/records")) { this.setState({selectedMenuKey: "/records"}); } else if (uri.includes("/webhooks")) { this.setState({selectedMenuKey: "/webhooks"}); } else if (uri.includes("/syncers")) { this.setState({selectedMenuKey: "/syncers"}); } else if (uri.includes("/certs")) { this.setState({selectedMenuKey: "/certs"}); } else if (uri.includes("/products")) { this.setState({selectedMenuKey: "/products"}); } else if (uri.includes("/payments")) { this.setState({selectedMenuKey: "/payments"}); } else if (uri.includes("/signup")) { this.setState({selectedMenuKey: "/signup"}); } else if (uri.includes("/login")) { this.setState({selectedMenuKey: "/login"}); } else if (uri.includes("/result")) { this.setState({selectedMenuKey: "/result"}); } else if (uri.includes("/sysinfo")) { this.setState({selectedMenuKey: "/sysinfo"}); } else { this.setState({selectedMenuKey: -1}); } } getAccessTokenParam(params) { // "/page?access_token=123" const accessToken = params.get("access_token"); return accessToken === null ? "" : `?accessToken=${accessToken}`; } getCredentialParams(params) { // "/page?username=abc&password=123" if (params.get("username") === null || params.get("password") === null) { return ""; } return `?username=${params.get("username")}&password=${params.get("password")}`; } getUrlWithoutQuery() { return window.location.toString().replace(window.location.search, ""); } getLanguageParam(params) { // "/page?language=en" const language = params.get("language"); if (language !== null) { Setting.setLanguage(language); return `language=${language}`; } return ""; } getLogo(themes) { if (themes.includes("dark")) { return `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256_dark.png`; } else { return `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`; } } setLanguage(account) { const language = account?.language; if (language !== "" && language !== i18next.language) { Setting.setLanguage(language); } } setTheme = (theme, initThemeAlgorithm) => { this.setState({ themeData: theme, }); if (initThemeAlgorithm) { this.setState({ logo: this.getLogo(Setting.getAlgorithmNames(theme)), themeAlgorithm: Setting.getAlgorithmNames(theme), }); } }; getAccount() { const params = new URLSearchParams(this.props.location.search); let query = this.getAccessTokenParam(params); if (query === "") { query = this.getCredentialParams(params); } const query2 = this.getLanguageParam(params); if (query2 !== "") { const url = window.location.toString().replace(new RegExp(`[?&]${query2}`), ""); window.history.replaceState({}, document.title, url); } if (query !== "") { window.history.replaceState({}, document.title, this.getUrlWithoutQuery()); } AuthBackend.getAccount(query) .then((res) => { let account = null; if (res.status === "ok") { account = res.data; account.organization = res.data2; this.setLanguage(account); this.setTheme(Setting.getThemeData(account.organization), Conf.InitThemeAlgorithm); } else { if (res.data !== "Please login first") { Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`); } } this.setState({ account: account, }); }); } logout() { this.setState({ expired: false, submitted: false, }); AuthBackend.logout() .then((res) => { if (res.status === "ok") { const owner = this.state.account.owner; this.setState({ account: null, themeAlgorithm: ["default"], }); Setting.showMessage("success", i18next.t("application:Logged out successfully")); const redirectUri = res.data2; if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") { Setting.goToLink(redirectUri); } else if (owner !== "built-in") { Setting.goToLink(`${window.location.origin}/login/${owner}`); } else { Setting.goToLinkSoft(this, "/"); } } else { Setting.showMessage("error", `Failed to log out: ${res.msg}`); } }); } onUpdateAccount(account) { this.setState({ account: account, }); } renderAvatar() { if (this.state.account.avatar === "") { return ( {Setting.getShortName(this.state.account.name)} ); } else { return ( {Setting.getShortName(this.state.account.name)} ); } } renderRightDropdown() { const items = []; items.push(Setting.getItem(<>  {i18next.t("account:My Account")}, "/account" )); items.push(Setting.getItem(<>  {i18next.t("account:Logout")}, "/logout")); const onClick = (e) => { if (e.key === "/account") { this.props.history.push("/account"); } else if (e.key === "/logout") { this.logout(); } }; return (
{ this.renderAvatar() }     {Setting.isMobile() ? null : Setting.getShortName(this.state.account.displayName)}        
); } renderAccountMenu() { if (this.state.account === undefined) { return null; } else if (this.state.account === null) { return null; } else { return ( {this.renderRightDropdown()} { this.setState({ themeAlgorithm: nextThemeAlgorithm, logo: this.getLogo(nextThemeAlgorithm), }); }} /> ); } } getMenuItems() { const res = []; if (this.state.account === null || this.state.account === undefined) { return []; } res.push(Setting.getItem({i18next.t("general:Home")}, "/")); if (Setting.isAdminUser(this.state.account)) { res.push(Setting.getItem({i18next.t("general:Organizations")}, "/organizations")); } if (Setting.isLocalAdminUser(this.state.account)) { res.push(Setting.getItem({i18next.t("general:Users")}, "/users" )); res.push(Setting.getItem({i18next.t("general:Roles")}, "/roles" )); res.push(Setting.getItem({i18next.t("general:Permissions")}, "/permissions" )); } if (Setting.isAdminUser(this.state.account)) { res.push(Setting.getItem({i18next.t("general:Models")}, "/models" )); res.push(Setting.getItem({i18next.t("general:Adapters")}, "/adapters" )); } if (Setting.isLocalAdminUser(this.state.account)) { res.push(Setting.getItem({i18next.t("general:Applications")}, "/applications" )); res.push(Setting.getItem({i18next.t("general:Providers")}, "/providers" )); res.push(Setting.getItem({i18next.t("general:Resources")}, "/resources" )); res.push(Setting.getItem({i18next.t("general:Records")}, "/records" )); } if (Setting.isAdminUser(this.state.account)) { res.push(Setting.getItem({i18next.t("general:Tokens")}, "/tokens" )); res.push(Setting.getItem({i18next.t("general:Sessions")}, "/sessions" )); res.push(Setting.getItem({i18next.t("general:Webhooks")}, "/webhooks" )); res.push(Setting.getItem({i18next.t("general:Syncers")}, "/syncers" )); res.push(Setting.getItem({i18next.t("general:Certs")}, "/certs" )); if (Conf.EnableExtraPages) { res.push(Setting.getItem({i18next.t("general:Products")}, "/products" )); res.push(Setting.getItem({i18next.t("general:Payments")}, "/payments" )); res.push(Setting.getItem({i18next.t("general:SysInfo")}, "/sysinfo" )); } res.push(Setting.getItem({i18next.t("general:Swagger")}, "/swagger" )); } return res; } renderHomeIfLoggedIn(component) { if (this.state.account !== null && this.state.account !== undefined) { return ; } else { return component; } } renderLoginIfNotLoggedIn(component) { if (this.state.account === null) { sessionStorage.setItem("from", window.location.pathname); return ; } else if (this.state.account === undefined) { return null; } else { return component; } } isStartPages() { return window.location.pathname.startsWith("/login") || window.location.pathname.startsWith("/signup") || window.location.pathname === "/"; } renderRouter() { return ( this.renderHomeIfLoggedIn()} /> this.renderHomeIfLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> } /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> {/* this.renderLoginIfNotLoggedIn()}/>*/} this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> } /> this.renderLoginIfNotLoggedIn()} /> } />} /> ); } onClose = () => { this.setState({ menuVisible: false, }); }; showMenu = () => { this.setState({ menuVisible: true, }); }; renderContent() { return ( {/* https://github.com/ant-design/ant-design/issues/40394 ant design bug. If it will be fixed, we can delete the code for control the color of Header*/}
{Setting.isMobile() ? null : (
)} {Setting.isMobile() ? : } { this.renderAccountMenu() }
{Setting.isMobile() ? this.renderRouter() : {this.renderRouter()} } {this.renderFooter()}
); } renderFooter() { return ( {!this.state.account ? null :
}
Powered by {"Casdoor"}
); } isDoorPages() { return this.isEntryPages() || window.location.pathname.startsWith("/callback"); } isEntryPages() { return window.location.pathname.startsWith("/signup") || window.location.pathname.startsWith("/login") || window.location.pathname.startsWith("/forget") || window.location.pathname.startsWith("/prompt") || window.location.pathname.startsWith("/cas") || window.location.pathname.startsWith("/auto-signup"); } renderPage() { if (this.isDoorPages()) { return ( { this.isEntryPages() ? { this.onUpdateAccount(account); }} updataThemeData={(nextThemeData) => { this.setState({ themeData: nextThemeData, }); localStorage.setItem("themeAlgorithm", Setting.getAlgorithmNames(nextThemeData).toString()); }} /> : } />} /> } { this.renderFooter() } ); } return ( { this.renderContent() } ); } render() { return ( {(this.state.account === undefined || this.state.account === null) ? : {this.state.account.organization?.displayName} } { this.renderPage() } ); } } export default withRouter(withTranslation()(App));