add password reset link to login page

This commit is contained in:
David Christofas
2022-03-16 15:50:45 +01:00
parent 51d1eb0182
commit 661baaab67
6 changed files with 33 additions and 6 deletions
@@ -0,0 +1,7 @@
Enhancement: Add password reset link to login page
Added a configurable passwort reset link to the login page.
It can be set via `IDP_PASSWORD_RESET_URI`. If the option is not set
the link will not be shown.
https://github.com/owncloud/ocis/pull/3329
+2 -1
View File
@@ -2,5 +2,6 @@ package config
// Service defines the available service configuration. // Service defines the available service configuration.
type Service struct { type Service struct {
Name string `ocisConfig:"-" yaml:"-"` Name string `ocisConfig:"-" yaml:"-"`
PasswordResetURI string `ocisConfig:"password_reset_uri" env:"IDP_PASSWORD_RESET_URI" desc:"The URI where a user can reset their password."`
} }
+2
View File
@@ -214,6 +214,8 @@ func (idp IDP) Index() http.HandlerFunc {
nonce := rndm.GenerateRandomString(32) nonce := rndm.GenerateRandomString(32)
indexHTML = bytes.Replace(indexHTML, []byte("__CSP_NONCE__"), []byte(nonce), 1) indexHTML = bytes.Replace(indexHTML, []byte("__CSP_NONCE__"), []byte(nonce), 1)
indexHTML = bytes.Replace(indexHTML, []byte("__PASSWORD_RESET_LINK__"), []byte(idp.config.Service.PasswordResetURI), 1)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
if _, err := w.Write(indexHTML); err != nil { if _, err := w.Write(indexHTML); err != nil {
+1 -1
View File
@@ -13,6 +13,6 @@
<noscript> <noscript>
You need to enable JavaScript to run this app. You need to enable JavaScript to run this app.
</noscript> </noscript>
<main id="root" class="oc-login-bg" data-path-prefix="__PATH_PREFIX__"></main> <main id="root" class="oc-login-bg" data-path-prefix="__PATH_PREFIX__" passwort-reset-link="__PASSWORD_RESET_LINK__"></main>
</body> </body>
</html> </html>
+9 -3
View File
@@ -9,6 +9,7 @@ import Button from '@material-ui/core/Button';
import CircularProgress from '@material-ui/core/CircularProgress'; import CircularProgress from '@material-ui/core/CircularProgress';
import green from '@material-ui/core/colors/green'; import green from '@material-ui/core/colors/green';
import Typography from '@material-ui/core/Typography'; import Typography from '@material-ui/core/Typography';
import Link from '@material-ui/core/Link';
import TextInput from '../../components/TextInput' import TextInput from '../../components/TextInput'
@@ -55,7 +56,8 @@ class Login extends React.PureComponent {
} }
render() { render() {
const { loading, errors, classes, username } = this.props; const { loading, errors, classes, username, passwordResetLink } = this.props;
const loginFailed = errors.http;
const hasError = errors.http || errors.username || errors.password; const hasError = errors.http || errors.username || errors.password;
const errorMessage = errors.http const errorMessage = errors.http
? <ErrorMessage error={errors.http}></ErrorMessage> ? <ErrorMessage error={errors.http}></ErrorMessage>
@@ -109,6 +111,8 @@ class Login extends React.PureComponent {
{hasError && <Typography id="oc-login-error-message" variant="subtitle2" component="span" color="error" {hasError && <Typography id="oc-login-error-message" variant="subtitle2" component="span" color="error"
className={classes.message}>{errorMessage}</Typography>} className={classes.message}>{errorMessage}</Typography>}
<div className={classes.wrapper}> <div className={classes.wrapper}>
{loginFailed && passwordResetLink && <Link id="oc-login-password-reset" href={passwordResetLink} variant="subtitle2">{"Reset password?"}</Link>}
<br />
<Button <Button
type="submit" type="submit"
color="primary" color="primary"
@@ -150,6 +154,7 @@ Login.propTypes = {
loading: PropTypes.string.isRequired, loading: PropTypes.string.isRequired,
username: PropTypes.string.isRequired, username: PropTypes.string.isRequired,
password: PropTypes.string.isRequired, password: PropTypes.string.isRequired,
passwordResetLink: PropTypes.string.isRequired,
errors: PropTypes.object.isRequired, errors: PropTypes.object.isRequired,
hello: PropTypes.object, hello: PropTypes.object,
query: PropTypes.object.isRequired, query: PropTypes.object.isRequired,
@@ -160,7 +165,7 @@ Login.propTypes = {
const mapStateToProps = (state) => { const mapStateToProps = (state) => {
const { loading, username, password, errors} = state.login; const { loading, username, password, errors} = state.login;
const { hello, query } = state.common; const { hello, query, passwordResetLink } = state.common;
return { return {
loading, loading,
@@ -168,7 +173,8 @@ const mapStateToProps = (state) => {
password, password,
errors, errors,
hello, hello,
query query,
passwordResetLink
}; };
}; };
+12 -1
View File
@@ -20,13 +20,24 @@ const defaultPathPrefix = (() => {
return pathPrefix; return pathPrefix;
})(); })();
const defaultPasswordResetLink = (() => {
const root = document.getElementById('root');
let link = root ? root.getAttribute('passwort-reset-link') : null;
if (!link || link === '__PASSWORD_RESET_LINK__') {
// Not replaced, probably we are running in debug mode or whatever. Use sane default.
link = '';
}
return link;
})();
const defaultState = { const defaultState = {
hello: null, hello: null,
error: null, error: null,
flow: flow, flow: flow,
query: query, query: query,
updateAvailable: false, updateAvailable: false,
pathPrefix: defaultPathPrefix pathPrefix: defaultPathPrefix,
passwordResetLink: defaultPasswordResetLink
}; };
function commonReducer(state = defaultState, action) { function commonReducer(state = defaultState, action) {