add Private ROute component

This commit is contained in:
Ruidy Nemausat 2020-04-03 16:28:52 +02:00
parent c5cb741b61
commit 058d70cb44
7 changed files with 127 additions and 130 deletions

View file

@ -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" />

View file

@ -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>
);
}

View 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>
);
};

View file

@ -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>
);
};

View file

@ -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}>

View 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} />;
};

View file

@ -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 />