1
0
mirror of https://github.com/0rangebananaspy/authelia.git synced 2024-09-14 22:47:21 +07:00

feat(web): add user display name to oidc consent view ()

This adds the current logged in users display name to the consent page as well as some other minor tweaks.

Closes 
This commit is contained in:
James Elliott 2022-04-08 12:50:55 +10:00 committed by GitHub
parent 5f51dcdb51
commit 90edf11b88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 108 additions and 20 deletions
internal/server/locales/en
web/src

View File

@ -61,5 +61,7 @@
"Must have at least one number": "Must have at least one number",
"Must have at least one special character": "Must have at least one special character",
"Must be at least {{len}} characters in length": "Must be at least {{len}} characters in length",
"Must not be more than {{len}} characters in length": "Must not be more than {{len}} characters in length"
"Must not be more than {{len}} characters in length": "Must not be more than {{len}} characters in length",
"Consent Request": "Consent Request",
"Client ID": "Client ID: {{client_id}}"
}

View File

@ -0,0 +1,13 @@
import React from "react";
import { render } from "@testing-library/react";
import TypographyWithTooltip from "@components/TypographyWithTootip";
it("renders without crashing", () => {
render(<TypographyWithTooltip value={"Example"} variant={"h5"} />);
});
it("renders with tooltip without crashing", () => {
render(<TypographyWithTooltip value={"Example"} tooltip={"A tooltip"} variant={"h5"} />);
});

View File

@ -0,0 +1,33 @@
import React, { Fragment } from "react";
import { Tooltip, Typography } from "@material-ui/core";
import { Variant } from "@material-ui/core/styles/createTypography";
import { CSSProperties } from "@material-ui/styles";
export interface Props {
variant: Variant;
value?: string;
style?: CSSProperties;
tooltip?: string;
tooltipStyle?: CSSProperties;
}
export default function TypographyWithTooltip(props: Props): JSX.Element {
return (
<Fragment>
{props.tooltip ? (
<Tooltip title={props.tooltip} style={props.tooltipStyle}>
<Typography variant={props.variant} style={props.style}>
{props.value}
</Typography>
</Tooltip>
) : (
<Typography variant={props.variant} style={props.style}>
{props.value}
</Typography>
)}
</Fragment>
);
}

View File

@ -1,6 +1,10 @@
import { useRemoteCall } from "@hooks/RemoteCall";
import { postUserInfo } from "@services/UserInfo";
import { getUserInfo, postUserInfo } from "@services/UserInfo";
export function useUserInfoPOST() {
return useRemoteCall(postUserInfo, []);
}
export function useUserInfoGET() {
return useRemoteCall(getUserInfo, []);
}

View File

@ -1,15 +1,19 @@
import React, { ReactNode } from "react";
import { Grid, makeStyles, Container, Typography, Link } from "@material-ui/core";
import { Grid, makeStyles, Container, Link } from "@material-ui/core";
import { grey } from "@material-ui/core/colors";
import { ReactComponent as UserSvg } from "@assets/images/user.svg";
import TypographyWithTooltip from "@components/TypographyWithTootip";
import { getLogoOverride } from "@utils/Configuration";
export interface Props {
id?: string;
children?: ReactNode;
title?: string;
titleTooltip?: string;
subtitle?: string;
subtitleTooltip?: string;
showBrand?: boolean;
}
@ -29,9 +33,16 @@ const LoginLayout = function (props: Props) {
</Grid>
{props.title ? (
<Grid item xs={12}>
<Typography variant="h5" className={style.title}>
{props.title}
</Typography>
<TypographyWithTooltip variant={"h5"} value={props.title} tooltip={props.titleTooltip} />
</Grid>
) : null}
{props.subtitle ? (
<Grid item xs={12}>
<TypographyWithTooltip
variant={"h6"}
value={props.subtitle}
tooltip={props.subtitleTooltip}
/>
</Grid>
) : null}
<Grid item xs={12} className={style.body}>
@ -66,6 +77,7 @@ const useStyles = makeStyles((theme) => ({
paddingRight: 32,
},
title: {},
subtitle: {},
icon: {
margin: theme.spacing(),
width: "64px",

View File

@ -1,7 +1,7 @@
import { SecondFactorMethod } from "@models/Methods";
import { UserInfo } from "@models/UserInfo";
import { UserInfo2FAMethodPath, UserInfoPath } from "@services/Api";
import { Post, PostWithOptionalResponse } from "@services/Client";
import { Get, Post, PostWithOptionalResponse } from "@services/Client";
export type Method2FA = "webauthn" | "totp" | "mobile_push";
@ -44,6 +44,11 @@ export async function postUserInfo(): Promise<UserInfo> {
return { ...res, method: toEnum(res.method) };
}
export async function getUserInfo(): Promise<UserInfo> {
const res = await Get<UserInfoPayload>(UserInfoPath);
return { ...res, method: toEnum(res.method) };
}
export function setPreferred2FAMethod(method: SecondFactorMethod) {
return PostWithOptionalResponse(UserInfo2FAMethodPath, { method: toString(method) } as MethodPreferencePayload);
}

View File

@ -19,6 +19,7 @@ import { IndexRoute } from "@constants/Routes";
import { useRequestedScopes } from "@hooks/Consent";
import { useNotifications } from "@hooks/NotificationsContext";
import { useRedirector } from "@hooks/Redirector";
import { useUserInfoGET } from "@hooks/UserInfo";
import LoginLayout from "@layouts/LoginLayout";
import { acceptConsent, rejectConsent } from "@services/Consent";
import LoadingPage from "@views/LoadingPage/LoadingPage";
@ -48,6 +49,18 @@ const ConsentView = function (props: Props) {
const [resp, fetch, , err] = useRequestedScopes();
const { t: translate } = useTranslation();
const [userInfo, fetchUserInfo, , fetchUserInfoError] = useUserInfoGET();
useEffect(() => {
fetchUserInfo();
}, [fetchUserInfo]);
useEffect(() => {
if (fetchUserInfoError) {
createErrorNotification("There was an issue retrieving user preferences");
}
}, [fetchUserInfoError, createErrorNotification]);
useEffect(() => {
if (err) {
navigate(IndexRoute);
@ -100,22 +113,28 @@ const ConsentView = function (props: Props) {
};
return (
<ComponentOrLoading ready={resp !== undefined}>
<LoginLayout id="consent-stage" title={`Permissions Request`} showBrand>
<ComponentOrLoading ready={resp !== undefined && userInfo !== undefined}>
<LoginLayout
id="consent-stage"
title={`${translate("Hi")} ${userInfo?.display_name}`}
subtitle={translate("Consent Request")}
showBrand
>
<Grid container>
<Grid item xs={12}>
<div>
{resp !== undefined && resp.client_description !== "" ? (
<Tooltip title={"Client ID: " + resp.client_id}>
<Typography className={classes.clientDescription}>
{resp.client_description}
</Typography>
</Tooltip>
) : (
<Tooltip title={"Client ID: " + resp?.client_id}>
<Typography className={classes.clientDescription}>{resp?.client_id}</Typography>
</Tooltip>
)}
<Tooltip
title={
translate("Client ID", { client_id: resp?.client_id }) ||
"Client ID: " + resp?.client_id
}
>
<Typography className={classes.clientDescription}>
{resp !== undefined && resp.client_description !== ""
? resp.client_description
: resp?.client_id}
</Typography>
</Tooltip>
</div>
</Grid>
<Grid item xs={12}>