From 54ab714a8fedc43cbb8bc4502ed05e7d87ee349f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 14 Mar 2025 10:50:58 +0100 Subject: [PATCH] add sign in page text (#377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer Co-authored-by: Alex Co-authored-by: Michael Barz --- services/idp/pkg/config/config.go | 2 +- services/idp/src/containers/Login/Login.jsx | 387 +++++++++++--------- 2 files changed, 207 insertions(+), 182 deletions(-) diff --git a/services/idp/pkg/config/config.go b/services/idp/pkg/config/config.go index 89231b00ca..b6faf6829e 100644 --- a/services/idp/pkg/config/config.go +++ b/services/idp/pkg/config/config.go @@ -99,7 +99,7 @@ type Settings struct { IdentifierRegistrationConf string `yaml:"-"` IdentifierScopesConf string `yaml:"-"` // unused IdentifierDefaultBannerLogo string - IdentifierDefaultSignInPageText string + IdentifierDefaultSignInPageText string `yaml:"default_sign_in_page_text" env:"IDP_DEFAULT_SIGNIN_PAGE_TEXT" desc:"" introductionVersion:"2.0.0"` IdentifierDefaultUsernameHintText string IdentifierUILocales []string diff --git a/services/idp/src/containers/Login/Login.jsx b/services/idp/src/containers/Login/Login.jsx index b9d6bba072..da65cf0d95 100644 --- a/services/idp/src/containers/Login/Login.jsx +++ b/services/idp/src/containers/Login/Login.jsx @@ -1,209 +1,234 @@ -import React, {useEffect, useMemo} from 'react'; -import PropTypes from 'prop-types'; -import {connect} from 'react-redux'; +import React, { useEffect, useMemo } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; -import {useTranslation} from 'react-i18next'; +import { useTranslation } from "react-i18next"; -import {withStyles} from '@material-ui/core/styles'; -import Button from '@material-ui/core/Button'; -import CircularProgress from '@material-ui/core/CircularProgress'; -import green from '@material-ui/core/colors/green'; -import Typography from '@material-ui/core/Typography'; -import Link from '@material-ui/core/Link'; +import { withStyles } from "@material-ui/core/styles"; +import Button from "@material-ui/core/Button"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import green from "@material-ui/core/colors/green"; +import Typography from "@material-ui/core/Typography"; +import Link from "@material-ui/core/Link"; -import TextInput from '../../components/TextInput' +import TextInput from "../../components/TextInput"; -import {updateInput, executeLogonIfFormValid, advanceLogonFlow} from '../../actions/login'; -import {ErrorMessage} from '../../errors'; +import { + updateInput, + executeLogonIfFormValid, + advanceLogonFlow, +} from "../../actions/login"; +import { ErrorMessage } from "../../errors"; -const styles = theme => ({ - buttonProgress: { - color: green[500], - position: 'absolute', - top: '50%', - left: '50%', - marginTop: -12, - marginLeft: -12 - }, - main: { - width: '100%' - }, - header: { - textAlign: 'center', - marginTop: 0, - marginBottom: theme.spacing(6) - }, - wrapper: { - position: 'relative', - width: '100%', - textAlign: 'center' - }, - message: { - marginTop: 5, - marginBottom: 5 - } +const styles = (theme) => ({ + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, + main: { + width: "100%", + }, + header: { + textAlign: "center", + marginTop: 0, + marginBottom: theme.spacing(6), + }, + wrapper: { + position: "relative", + width: "100%", + textAlign: "center", + }, + message: { + marginTop: 5, + marginBottom: 5, + }, }); function Login(props) { - const { - hello, - query, - dispatch, - history, - loading, - errors, - classes, - username, - password, - passwordResetLink, - } = props; + const { + hello, + query, + dispatch, + history, + loading, + errors, + classes, + username, + password, + passwordResetLink, + branding, + } = props; - const {t} = useTranslation(); - const loginFailed = errors.http; - const hasError = errors.http || errors.username || errors.password; - const errorMessage = errors.http - ? - : (errors.username - ? - : ); - const extraPropsUsername = { - "aria-invalid": (errors.username || errors.http) ? 'true' : 'false' - }; - const extraPropsPassword = { - "aria-invalid": (errors.password || errors.http) ? 'true' : 'false', - }; + const { t } = useTranslation(); + const loginFailed = errors.http; + const hasError = errors.http || errors.username || errors.password; + const errorMessage = errors.http ? ( + + ) : errors.username ? ( + + ) : ( + + ); + const extraPropsUsername = { + "aria-invalid": errors.username || errors.http ? "true" : "false", + }; + const extraPropsPassword = { + "aria-invalid": errors.password || errors.http ? "true" : "false", + }; - if (errors.username || errors.http) { - extraPropsUsername['extraClassName'] = 'error'; - extraPropsUsername['aria-describedby'] = 'oc-login-error-message'; + if (errors.username || errors.http) { + extraPropsUsername["extraClassName"] = "error"; + extraPropsUsername["aria-describedby"] = "oc-login-error-message"; + } + + if (errors.password || errors.http) { + extraPropsPassword["extraClassName"] = "error"; + extraPropsPassword["aria-describedby"] = "oc-login-error-message"; + } + + useEffect(() => { + if (hello && hello.state && history.action !== "PUSH") { + if (!query.prompt || query.prompt.indexOf("select_account") === -1) { + dispatch(advanceLogonFlow(true, history)); + return; + } + + history.replace( + `/chooseaccount${history.location.search}${history.location.hash}` + ); + return; } + }); - if (errors.password || errors.http) { - extraPropsPassword['extraClassName'] = 'error'; - extraPropsPassword['aria-describedby'] = 'oc-login-error-message'; - } + const handleChange = (name) => (event) => { + dispatch(updateInput(name, event.target.value)); + }; - useEffect(() => { - if (hello && hello.state && history.action !== 'PUSH') { - if (!query.prompt || query.prompt.indexOf('select_account') === -1) { - dispatch(advanceLogonFlow(true, history)); - return; - } + const handleNextClick = (event) => { + event.preventDefault(); - history.replace(`/chooseaccount${history.location.search}${history.location.hash}`); - return; + dispatch(executeLogonIfFormValid(username, password, false)).then( + (response) => { + if (response.success) { + dispatch(advanceLogonFlow(response.success, history)); } - }); - - const handleChange = (name) => (event) => { - dispatch(updateInput(name, event.target.value)); - }; - - const handleNextClick = (event) => { - event.preventDefault(); - - dispatch(executeLogonIfFormValid(username, password, false)).then((response) => { - if (response.success) { - dispatch(advanceLogonFlow(response.success, history)); - } - }); - }; - - const usernamePlaceHolder = useMemo(() => { - if (hello?.details?.branding?.usernameHintText) { - switch (hello.details.branding.usernameHintText) { - case "Username": - break; - case "Email": - return t("konnect.login.usernameField.placeholder.email", "Email"); - case "Identity": - return t("konnect.login.usernameField.placeholder.identity", "Identity"); - default: - return hello.details.branding.usernameHintText; - } - } - - return t("konnect.login.usernameField.placeholder.username", "Username"); - }, [hello, t]); - - return ( -
-

{t("konnect.login.headline", "Sign in")}

-
handleNextClick(event)}> - - - {hasError && {errorMessage}} -
- {loginFailed && passwordResetLink && {"Reset password?"}} - - {loading && } -
- -
+ } ); + }; + + return ( +
+

+ {" "} + {t("konnect.login.headline", "Sign in")} +

+ {branding?.signinPageText && ( + + )} +
handleNextClick(event)} + > + + + {hasError && ( + + {errorMessage} + + )} +
+ {loginFailed && passwordResetLink && ( + + {"Reset password?"} + + )} + + {loading && ( + + )} +
+ +
+ ); } Login.propTypes = { - classes: PropTypes.object.isRequired, + classes: PropTypes.object.isRequired, - loading: PropTypes.string.isRequired, - username: PropTypes.string.isRequired, - password: PropTypes.string.isRequired, - passwordResetLink: PropTypes.string.isRequired, - errors: PropTypes.object.isRequired, - branding: PropTypes.object, - hello: PropTypes.object, - query: PropTypes.object.isRequired, + loading: PropTypes.string.isRequired, + username: PropTypes.string.isRequired, + password: PropTypes.string.isRequired, + passwordResetLink: PropTypes.string.isRequired, + errors: PropTypes.object.isRequired, + branding: PropTypes.object, + hello: PropTypes.object, + query: PropTypes.object.isRequired, - dispatch: PropTypes.func.isRequired, - history: PropTypes.object.isRequired + dispatch: PropTypes.func.isRequired, + history: PropTypes.object.isRequired, }; const mapStateToProps = (state) => { - const {loading, username, password, errors} = state.login; - const {branding, hello, query, passwordResetLink} = state.common; + const { loading, username, password, errors } = state.login; + const { branding, hello, query, passwordResetLink } = state.common; - return { - loading, - username, - password, - errors, - branding, - hello, - query, - passwordResetLink - }; + return { + loading, + username, + password, + errors, + branding, + hello, + query, + passwordResetLink, + }; }; export default connect(mapStateToProps)(withStyles(styles)(Login));