mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-06 00:36:39 +00:00
add Private ROute component
This commit is contained in:
parent
c5cb741b61
commit
058d70cb44
7 changed files with 127 additions and 130 deletions
|
|
@ -14,9 +14,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.1">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.1.4" />
|
||||
<PackageReference Include="Moq" Version="4.13.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import React from "react";
|
||||
import { Router } from "react-router-dom";
|
||||
import * as createHistory from "history";
|
||||
import Layout from "./pages/Layout";
|
||||
import { useAuth0 } from "./authentication/auth0";
|
||||
|
||||
// import history from "./utils/history";
|
||||
import * as createHistory from "history";
|
||||
export const history = createHistory.createBrowserHistory();
|
||||
|
||||
export default function App() {
|
||||
const { loading } = useAuth0();
|
||||
|
||||
|
|
@ -14,10 +13,8 @@ export default function App() {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Router history={history}>
|
||||
<Layout />
|
||||
</Router>
|
||||
</>
|
||||
<Router history={history}>
|
||||
<Layout />
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
90
client/src/authentication/auth0.jsx
Normal file
90
client/src/authentication/auth0.jsx
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// src/react-auth0-spa.js
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import createAuth0Client from "@auth0/auth0-spa-js";
|
||||
|
||||
const DEFAULT_REDIRECT_CALLBACK = () =>
|
||||
window.history.replaceState({}, document.title, window.location.pathname);
|
||||
|
||||
export const Auth0Context = React.createContext();
|
||||
export const useAuth0 = () => useContext(Auth0Context);
|
||||
export const Auth0Provider = ({
|
||||
children,
|
||||
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
|
||||
...initOptions
|
||||
}) => {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState();
|
||||
const [user, setUser] = useState();
|
||||
const [auth0Client, setAuth0] = useState();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [popupOpen, setPopupOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const initAuth0 = async () => {
|
||||
const auth0FromHook = await createAuth0Client(initOptions);
|
||||
setAuth0(auth0FromHook);
|
||||
|
||||
if (
|
||||
window.location.search.includes("code=") &&
|
||||
window.location.search.includes("state=")
|
||||
) {
|
||||
const { appState } = await auth0FromHook.handleRedirectCallback();
|
||||
onRedirectCallback(appState);
|
||||
}
|
||||
|
||||
const isAuthenticated = await auth0FromHook.isAuthenticated();
|
||||
|
||||
setIsAuthenticated(isAuthenticated);
|
||||
|
||||
if (isAuthenticated) {
|
||||
const user = await auth0FromHook.getUser();
|
||||
setUser(user);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
initAuth0();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const loginWithPopup = async (params = {}) => {
|
||||
setPopupOpen(true);
|
||||
try {
|
||||
await auth0Client.loginWithPopup(params);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
setPopupOpen(false);
|
||||
}
|
||||
const user = await auth0Client.getUser();
|
||||
setUser(user);
|
||||
setIsAuthenticated(true);
|
||||
};
|
||||
|
||||
const handleRedirectCallback = async () => {
|
||||
setLoading(true);
|
||||
await auth0Client.handleRedirectCallback();
|
||||
const user = await auth0Client.getUser();
|
||||
setLoading(false);
|
||||
setIsAuthenticated(true);
|
||||
setUser(user);
|
||||
};
|
||||
return (
|
||||
<Auth0Context.Provider
|
||||
value={{
|
||||
isAuthenticated,
|
||||
user,
|
||||
loading,
|
||||
popupOpen,
|
||||
loginWithPopup,
|
||||
handleRedirectCallback,
|
||||
getIdTokenClaims: (...p) => auth0Client.getIdTokenClaims(...p),
|
||||
loginWithRedirect: (...p) => auth0Client.loginWithRedirect(...p),
|
||||
getTokenSilently: (...p) => auth0Client.getTokenSilently(...p),
|
||||
getTokenWithPopup: (...p) => auth0Client.getTokenWithPopup(...p),
|
||||
logout: (...p) => auth0Client.logout(...p)
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Auth0Context.Provider>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
import React, { useState, useEffect, useContext } from "react";
|
||||
import createAuth0Client from "@auth0/auth0-spa-js";
|
||||
import Auth0Client from "@auth0/auth0-spa-js/dist/typings/Auth0Client";
|
||||
|
||||
interface IAuth0Context {
|
||||
isAuthenticated: boolean;
|
||||
user: any;
|
||||
loading: boolean;
|
||||
popupOpen: boolean;
|
||||
loginWithPopup(options: PopupLoginOptions): Promise<void>;
|
||||
handleRedirectCallback(): Promise<RedirectLoginResult>;
|
||||
getIdTokenClaims(o?: getIdTokenClaimsOptions): Promise<IdToken>;
|
||||
loginWithRedirect(o: RedirectLoginOptions): Promise<void>;
|
||||
getTokenSilently(o?: GetTokenSilentlyOptions): Promise<string | undefined>;
|
||||
getTokenWithPopup(o?: GetTokenWithPopupOptions): Promise<string | undefined>;
|
||||
logout(o?: LogoutOptions): void;
|
||||
}
|
||||
export interface IAuth0ProviderOptions {
|
||||
children: React.ReactElement;
|
||||
onRedirectCallback?(result: RedirectLoginResult): void;
|
||||
}
|
||||
|
||||
const DEFAULT_REDIRECT_CALLBACK: () => void = () =>
|
||||
window.history.replaceState({}, document.title, window.location.pathname);
|
||||
|
||||
export const Auth0Context: React.Context<IAuth0Context | null> = React.createContext<IAuth0Context | null>(
|
||||
null
|
||||
);
|
||||
export const useAuth0: () => IAuth0Context = () => useContext(Auth0Context)!;
|
||||
export const Auth0Provider = ({
|
||||
children,
|
||||
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
|
||||
...initOptions
|
||||
}: IAuth0ProviderOptions & Auth0ClientOptions) => {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
const [user, setUser] = useState();
|
||||
const [auth0Client, setAuth0] = useState<Auth0Client>();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [popupOpen, setPopupOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const initAuth0 = async () => {
|
||||
const auth0FromHook = await createAuth0Client(initOptions);
|
||||
setAuth0(auth0FromHook);
|
||||
|
||||
if (window.location.search.includes("code=")) {
|
||||
const { appState } = await auth0FromHook.handleRedirectCallback();
|
||||
onRedirectCallback(appState);
|
||||
}
|
||||
|
||||
const isAuthenticated = await auth0FromHook.isAuthenticated();
|
||||
|
||||
setIsAuthenticated(isAuthenticated);
|
||||
|
||||
if (isAuthenticated) {
|
||||
const user = await auth0FromHook.getUser();
|
||||
setUser(user);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
initAuth0();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const loginWithPopup = async (o: PopupLoginOptions) => {
|
||||
setPopupOpen(true);
|
||||
try {
|
||||
await auth0Client!.loginWithPopup(o);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
setPopupOpen(false);
|
||||
}
|
||||
const user = await auth0Client!.getUser();
|
||||
setUser(user);
|
||||
setIsAuthenticated(true);
|
||||
};
|
||||
|
||||
const handleRedirectCallback = async () => {
|
||||
setLoading(true);
|
||||
const result = await auth0Client!.handleRedirectCallback();
|
||||
const user = await auth0Client!.getUser();
|
||||
setLoading(false);
|
||||
setIsAuthenticated(true);
|
||||
setUser(user);
|
||||
return result;
|
||||
};
|
||||
return (
|
||||
<Auth0Context.Provider
|
||||
value={{
|
||||
isAuthenticated,
|
||||
user,
|
||||
loading,
|
||||
popupOpen,
|
||||
loginWithPopup,
|
||||
handleRedirectCallback,
|
||||
getIdTokenClaims: (o: getIdTokenClaimsOptions | undefined) =>
|
||||
auth0Client!.getIdTokenClaims(o),
|
||||
loginWithRedirect: (o: RedirectLoginOptions) =>
|
||||
auth0Client!.loginWithRedirect(o),
|
||||
getTokenSilently: (o: GetTokenSilentlyOptions | undefined) =>
|
||||
auth0Client!.getTokenSilently(o),
|
||||
getTokenWithPopup: (o: GetTokenWithPopupOptions | undefined) =>
|
||||
auth0Client!.getTokenWithPopup(o),
|
||||
logout: (o: LogoutOptions | undefined) => auth0Client!.logout(o)
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Auth0Context.Provider>
|
||||
);
|
||||
};
|
||||
|
|
@ -17,10 +17,9 @@ import {
|
|||
makeStyles,
|
||||
Theme,
|
||||
Grid,
|
||||
Typography,
|
||||
Chip
|
||||
Typography
|
||||
} from "@material-ui/core";
|
||||
import { Timer, InfoSharp } from "@material-ui/icons";
|
||||
import { Timer } from "@material-ui/icons";
|
||||
|
||||
interface IProps {
|
||||
viewModel: TicketVM;
|
||||
|
|
@ -52,7 +51,6 @@ export const TicketPage: FC<IProps> = ({ viewModel }) => {
|
|||
// let notes: string = "";
|
||||
const classes = useStyles();
|
||||
|
||||
const infos: InfoProps = { status, category, impact, difficulty };
|
||||
return (
|
||||
<Container maxWidth="md">
|
||||
<div className={classes.root}>
|
||||
|
|
|
|||
24
client/src/utils/PrivateRoute.jsx
Normal file
24
client/src/utils/PrivateRoute.jsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { Route } from "react-router-dom";
|
||||
import { useAuth0 } from "../authentication/auth0";
|
||||
|
||||
export const PrivateRoute = ({ component: Component, path, ...rest }) => {
|
||||
const { loading, isAuthenticated, loginWithRedirect } = useAuth0();
|
||||
|
||||
useEffect(() => {
|
||||
if (loading || isAuthenticated) {
|
||||
return;
|
||||
}
|
||||
const fn = async () => {
|
||||
await loginWithRedirect({
|
||||
appState: { targetUrl: window.location.pathname }
|
||||
});
|
||||
};
|
||||
fn();
|
||||
}, [loading, isAuthenticated, loginWithRedirect, path]);
|
||||
|
||||
const render = props =>
|
||||
isAuthenticated === true ? <Component {...props} /> : null;
|
||||
|
||||
return <Route path={path} render={render} {...rest} />;
|
||||
};
|
||||
|
|
@ -7,13 +7,14 @@ import { UserController } from "../controllers/UserController";
|
|||
import { TicketController } from "../controllers/TicketController";
|
||||
import { NotFoundPage } from "../pages/NotFoundPage";
|
||||
import { TestPage } from "../pages/TestPage";
|
||||
import { PrivateRoute } from "./PrivateRoute";
|
||||
|
||||
export const AppRouter = () => {
|
||||
return (
|
||||
<Switch>
|
||||
<Route exact path="/test">
|
||||
{/* <PrivateRoute exact path="/test">
|
||||
<TestPage />
|
||||
</Route>
|
||||
</PrivateRoute> */}
|
||||
|
||||
<Route exact path="/">
|
||||
<HomeController />
|
||||
|
|
|
|||
Loading…
Reference in a new issue