add signed out page

This commit is contained in:
Caleb Doxsey 2023-09-19 17:40:51 -06:00
parent f649d9b1bc
commit dce25e12d5
6 changed files with 77 additions and 18 deletions

View file

@ -89,6 +89,7 @@ func (a *Authenticate) mountDashboard(r *mux.Router) {
// routes that don't need a session:
sr.Path("/sign_out").Handler(httputil.HandlerFunc(a.SignOut))
sr.Path("/signed_out").Handler(handlers.SignedOut(handlers.SignedOutData{})).Methods(http.MethodGet)
// routes that need a session:
sr = sr.NewRoute().Subrouter()
@ -266,16 +267,25 @@ func (a *Authenticate) signOutRedirect(w http.ResponseWriter, r *http.Request) e
rawIDToken := a.revokeSession(ctx, w, r)
signOutURL := ""
authenticateURL, err := options.GetAuthenticateURL()
if err != nil {
return fmt.Errorf("error getting authenticate url: %w", err)
}
signOutRedirectURL, err := options.GetSignOutRedirectURL()
if err != nil {
return err
}
if signOutRedirectURL != nil {
signOutURL = signOutRedirectURL.String()
}
var signOutURL string
if uri := r.FormValue(urlutil.QueryRedirectURI); uri != "" {
signOutURL = uri
} else if signOutRedirectURL != nil {
signOutURL = signOutRedirectURL.String()
} else {
signOutURL = authenticateURL.ResolveReference(&url.URL{
Path: "/.pomerium/signed_out",
}).String()
}
if idpSignOutURL, err := authenticator.GetSignOutURL(rawIDToken, signOutURL); err == nil {
@ -284,11 +294,8 @@ func (a *Authenticate) signOutRedirect(w http.ResponseWriter, r *http.Request) e
log.Warn(r.Context()).Err(err).Msg("authenticate: failed to get sign out url for authenticator")
}
if signOutURL != "" {
httputil.Redirect(w, r, signOutURL, http.StatusFound)
return nil
}
return httputil.NewError(http.StatusOK, errors.New("user logged out"))
httputil.Redirect(w, r, signOutURL, http.StatusFound)
return nil
}
// reauthenticateOrFail starts the authenticate process by redirecting the

View file

@ -0,0 +1,23 @@
package handlers
import (
"net/http"
"github.com/pomerium/pomerium/internal/httputil"
"github.com/pomerium/pomerium/ui"
)
// SignedOutData is the data for the SignedOut page.
type SignedOutData struct{}
// ToJSON converts the data into a JSON map.
func (data SignedOutData) ToJSON() map[string]interface{} {
return map[string]interface{}{}
}
// SignedOut returns a handler that renders the signed out page.
func SignedOut(data SignedOutData) http.Handler {
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
return ui.ServePage(w, r, "SignedOut", data.ToJSON())
})
}

View file

@ -1,12 +1,13 @@
import Box from "@mui/material/Box";
import CssBaseline from "@mui/material/CssBaseline";
import { ThemeProvider } from "@mui/material/styles";
import React, {FC, useLayoutEffect} from "react";
import React, { FC, useLayoutEffect } from "react";
import ErrorPage from "./components/ErrorPage";
import Footer from "./components/Footer";
import Header from "./components/Header";
import SignOutConfirmPage from "./components/SignOutConfirmPage";
import SignedOutPage from "./components/SignedOutPage";
import { ToolbarOffset } from "./components/ToolbarOffset";
import UserInfoPage from "./components/UserInfoPage";
import WebAuthnRegistrationPage from "./components/WebAuthnRegistrationPage";
@ -27,6 +28,9 @@ const App: FC = () => {
case "SignOutConfirm":
body = <SignOutConfirmPage data={data} />;
break;
case "SignedOut":
body = <SignedOutPage data={data} />;
break;
case "DeviceEnrolled":
case "UserInfo":
body = <UserInfoPage data={data} />;
@ -38,18 +42,18 @@ const App: FC = () => {
useLayoutEffect(() => {
const favicon = document.getElementById(
'favicon'
"favicon"
) as HTMLAnchorElement | null;
if (favicon) {
favicon.href = data?.faviconUrl || '/.pomerium/favicon.ico';
favicon.href = data?.faviconUrl || "/.pomerium/favicon.ico";
}
const extraFaviconLinks = document.getElementsByClassName(
'pomerium_favicon'
"pomerium_favicon"
) as HTMLCollectionOf<HTMLAnchorElement> | null;
for (const link of extraFaviconLinks) {
link.style.display = data?.faviconUrl ? 'none' : '';
link.style.display = data?.faviconUrl ? "none" : "";
}
}, [])
}, []);
return (
<ThemeProvider theme={theme}>

View file

@ -57,6 +57,8 @@ const Header: FC<HeaderProps> = ({ includeSidebar, data }) => {
get(data, "user.claims.picture") ||
get(data, "profile.claims.picture") ||
null;
const showAvatar =
data?.page !== "SignOutConfirm" && data?.page !== "SignedOut";
const handleDrawerOpen = () => {
setDrawerOpen(true);
@ -122,9 +124,11 @@ const Header: FC<HeaderProps> = ({ includeSidebar, data }) => {
</a>
)}
<Box flexGrow={1} />
<IconButton color="inherit" onClick={handleMenuOpen}>
<Avatar name={userName} url={userPictureUrl} />
</IconButton>
{showAvatar && (
<IconButton color="inherit" onClick={handleMenuOpen}>
<Avatar name={userName} url={userPictureUrl} />
</IconButton>
)}
<Menu
onClose={handleMenuClose}
anchorOrigin={{

View file

@ -0,0 +1,16 @@
import { Alert } from "@mui/material";
import Container from "@mui/material/Container";
import React, { FC } from "react";
import { SignedOutPageData } from "src/types";
type SignedOutPageProps = {
data: SignedOutPageData;
};
const SignedOutPage: FC<SignedOutPageProps> = ({ data }) => {
return (
<Container>
<Alert color="info">User has been Logged Out</Alert>
</Container>
);
};
export default SignedOutPage;

View file

@ -132,6 +132,10 @@ export type SignOutConfirmPageData = BasePageData & {
url: string;
};
export type SignedOutPageData = BasePageData & {
page: "SignedOut";
};
export type UserInfoPageData = BasePageData &
UserInfoData & {
page: "UserInfo";
@ -150,6 +154,7 @@ export type PageData =
| ErrorPageData
| DeviceEnrolledPageData
| SignOutConfirmPageData
| SignedOutPageData
| UserInfoPageData
| WebAuthnRegistrationPageData;