fleet/frontend/components/forms/RegistrationForm/AdminDetails/AdminDetails.jsx
Scott Gress dc4fd676c5
Update password requirements check when setting up (#32261)
for #31876 

# Details

This PR updates the validation for password requirements to be
consistent in all places, and to show more specific error messages when
the entered password does not meet the requirements.

Previously the `valid_password` helper just returned a boolean
indicating whether a password was valid. It now returns an object with
`isValid`, `error` and `error_code` so that different types of password
issues can be surfaced. This allows us to continue having a single
source of truth for password validation, while providing more helpful
error messages when a password doesn't meet our criteria.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

## Testing

- [X] Added/updated automated tests
- [X] QA'd all new/changed functionality manually
  - [X] First time setup (adding the initial user)
  - [X] Add user in settings -> manage users
  - [X] Changer user password in settings -> manage users
  - [X] Password reset form
2025-08-26 16:59:05 -05:00

84 lines
2.5 KiB
JavaScript

import React, { Component } from "react";
import PropTypes from "prop-types";
import Form from "components/forms/Form";
import formFieldInterface from "interfaces/form_field";
import Button from "components/buttons/Button";
import InputField from "components/forms/fields/InputField";
import helpers from "./helpers";
const formFields = ["name", "password", "password_confirmation", "email"];
const { validate } = helpers;
class AdminDetails extends Component {
static propTypes = {
className: PropTypes.string,
currentPage: PropTypes.bool,
fields: PropTypes.shape({
name: formFieldInterface.isRequired,
email: formFieldInterface.isRequired,
password: formFieldInterface.isRequired,
password_confirmation: formFieldInterface.isRequired,
}).isRequired,
handleSubmit: PropTypes.func.isRequired,
};
componentDidUpdate(prevProps) {
if (
this.props.currentPage &&
this.props.currentPage !== prevProps.currentPage
) {
// Component has a transition duration of 300ms set in
// RegistrationForm/_styles.scss. We need to wait 300ms before
// calling .focus() to preserve smooth transition.
setTimeout(() => {
this.firstInput.input.focus();
}, 300);
}
}
render() {
const { className, currentPage, fields, handleSubmit } = this.props;
const tabIndex = currentPage ? 0 : -1;
return (
<form onSubmit={handleSubmit} className={className} autoComplete="off">
<p>Additional admins can be designated within the Fleet app.</p>
<InputField
{...fields.name}
label="Full name"
tabIndex={tabIndex}
autofocus={currentPage}
ref={(input) => {
this.firstInput = input;
}}
inputOptions={{
maxLength: "80",
}}
/>
<InputField {...fields.email} label="Email" tabIndex={tabIndex} />
<InputField
{...fields.password}
label="Password"
type="password"
tabIndex={tabIndex}
helpText="12-48 characters, with at least 1 number (e.g. 0 - 9) and 1 symbol (e.g. &*#)."
/>
<InputField
{...fields.password_confirmation}
type="password"
tabIndex={tabIndex}
label="Confirm password"
/>
<Button type="submit" tabIndex={tabIndex} disabled={!currentPage}>
Next
</Button>
</form>
);
}
}
export default Form(AdminDetails, {
fields: formFields,
validate,
});