do not use custom validator to check if password confirmation matches password
This commit is contained in:
parent
dfdc90b686
commit
cf42f5b2a0
@ -624,12 +624,6 @@ export type Validators = Partial<{
|
|||||||
"person-name-prohibited-characters": Validators.DoIgnoreEmpty & Validators.ErrorMessage;
|
"person-name-prohibited-characters": Validators.DoIgnoreEmpty & Validators.ErrorMessage;
|
||||||
uri: Validators.DoIgnoreEmpty;
|
uri: Validators.DoIgnoreEmpty;
|
||||||
"username-prohibited-characters": Validators.DoIgnoreEmpty & Validators.ErrorMessage;
|
"username-prohibited-characters": Validators.DoIgnoreEmpty & Validators.ErrorMessage;
|
||||||
/** Made up validator that only exists in Keycloakify */
|
|
||||||
_compareToOther: Validators.DoIgnoreEmpty &
|
|
||||||
Validators.ErrorMessage & {
|
|
||||||
name: string;
|
|
||||||
shouldBe: "equal" | "different";
|
|
||||||
};
|
|
||||||
options: Validators.Options;
|
options: Validators.Options;
|
||||||
multivalued: Validators.DoIgnoreEmpty & Validators.Range;
|
multivalued: Validators.DoIgnoreEmpty & Validators.Range;
|
||||||
}>;
|
}>;
|
||||||
|
@ -59,8 +59,8 @@ export type KcContextLike = {
|
|||||||
export type ParamsOfUseUserProfileForm = {
|
export type ParamsOfUseUserProfileForm = {
|
||||||
kcContext: KcContextLike;
|
kcContext: KcContextLike;
|
||||||
passwordValidators?: Validators;
|
passwordValidators?: Validators;
|
||||||
requirePasswordConfirmation?: boolean;
|
|
||||||
i18n: I18n;
|
i18n: I18n;
|
||||||
|
passwordConfirmationDisabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ReturnTypeOfUseUserProfileForm = {
|
export type ReturnTypeOfUseUserProfileForm = {
|
||||||
@ -74,7 +74,7 @@ export type ReturnTypeOfUseUserProfileForm = {
|
|||||||
* artificial password related attributes only if kcContext.passwordRequired === true
|
* artificial password related attributes only if kcContext.passwordRequired === true
|
||||||
*/
|
*/
|
||||||
export function useUserProfileForm(params: ParamsOfUseUserProfileForm): ReturnTypeOfUseUserProfileForm {
|
export function useUserProfileForm(params: ParamsOfUseUserProfileForm): ReturnTypeOfUseUserProfileForm {
|
||||||
const { kcContext, passwordValidators = {}, i18n } = params;
|
const { kcContext, passwordValidators = {}, i18n, passwordConfirmationDisabled = false } = params;
|
||||||
|
|
||||||
const attributesWithPassword = useMemo(() => {
|
const attributesWithPassword = useMemo(() => {
|
||||||
const attributesWithPassword: Attribute[] = [];
|
const attributesWithPassword: Attribute[] = [];
|
||||||
@ -107,14 +107,7 @@ export function useUserProfileForm(params: ParamsOfUseUserProfileForm): ReturnTy
|
|||||||
"displayName": id<`\${${MessageKey}}`>("${passwordConfirm}"),
|
"displayName": id<`\${${MessageKey}}`>("${passwordConfirm}"),
|
||||||
"required": true,
|
"required": true,
|
||||||
"readOnly": false,
|
"readOnly": false,
|
||||||
"validators": {
|
"validators": {},
|
||||||
"_compareToOther": {
|
|
||||||
"name": "password",
|
|
||||||
"ignore.empty.value": true,
|
|
||||||
"shouldBe": "equal",
|
|
||||||
"error-message": id<`\${${MessageKey}}`>("${invalidPasswordConfirmMessage}")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"annotations": {},
|
"annotations": {},
|
||||||
"html5DataAnnotations": {},
|
"html5DataAnnotations": {},
|
||||||
"autocomplete": "new-password",
|
"autocomplete": "new-password",
|
||||||
@ -142,7 +135,7 @@ export function useUserProfileForm(params: ParamsOfUseUserProfileForm): ReturnTy
|
|||||||
type State = FormFieldState_internal[];
|
type State = FormFieldState_internal[];
|
||||||
|
|
||||||
const [state, dispatchFormAction] = useReducer(
|
const [state, dispatchFormAction] = useReducer(
|
||||||
(state: State, params: FormAction): State => {
|
function reducer(state: State, params: FormAction): State {
|
||||||
if (params.action === "add value to multi-valued attribute") {
|
if (params.action === "add value to multi-valued attribute") {
|
||||||
const formFieldStates = state.filter(({ name }) => name === params.name);
|
const formFieldStates = state.filter(({ name }) => name === params.name);
|
||||||
|
|
||||||
@ -170,6 +163,23 @@ export function useUserProfileForm(params: ParamsOfUseUserProfileForm): ReturnTy
|
|||||||
formFieldState.hasLostFocusAtLeastOnce = true;
|
formFieldState.hasLostFocusAtLeastOnce = true;
|
||||||
return state;
|
return state;
|
||||||
case "update value":
|
case "update value":
|
||||||
|
update_password_confirm: {
|
||||||
|
if (params.name !== "password") {
|
||||||
|
break update_password_confirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!passwordConfirmationDisabled) {
|
||||||
|
break update_password_confirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = reducer(state, {
|
||||||
|
"action": "update value",
|
||||||
|
"name": "password-confirm",
|
||||||
|
"index": 0,
|
||||||
|
"newValue": params.newValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
formFieldState.value = params.newValue;
|
formFieldState.value = params.newValue;
|
||||||
formFieldState.errors = getErrors({
|
formFieldState.errors = getErrors({
|
||||||
"name": params.name,
|
"name": params.name,
|
||||||
@ -336,6 +346,28 @@ function useGetErrors(params: {
|
|||||||
|
|
||||||
const errors: FormFieldError[] = [];
|
const errors: FormFieldError[] = [];
|
||||||
|
|
||||||
|
password_confirm_matches_password: {
|
||||||
|
if (name !== "password-confirm") {
|
||||||
|
break password_confirm_matches_password;
|
||||||
|
}
|
||||||
|
|
||||||
|
const passwordFieldValue = fieldValues.find(fieldValue => fieldValue.name === "password");
|
||||||
|
|
||||||
|
assert(passwordFieldValue !== undefined);
|
||||||
|
|
||||||
|
if (passwordFieldValue.value === value) {
|
||||||
|
break password_confirm_matches_password;
|
||||||
|
}
|
||||||
|
|
||||||
|
const msgArgs = ["invalidPasswordConfirmMessage"] as const;
|
||||||
|
|
||||||
|
errors.push({
|
||||||
|
"validatorName": undefined,
|
||||||
|
"errorMessage": <Fragment key={errors.length}>{msg(...msgArgs)}</Fragment>,
|
||||||
|
"errorMessageStr": msgStr(...msgArgs)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const { validators } = attribute;
|
const { validators } = attribute;
|
||||||
|
|
||||||
required_field: {
|
required_field: {
|
||||||
@ -392,62 +424,6 @@ function useGetErrors(params: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validator_x: {
|
|
||||||
const validatorName = "_compareToOther";
|
|
||||||
|
|
||||||
const validator = validators[validatorName];
|
|
||||||
|
|
||||||
if (validator === undefined) {
|
|
||||||
break validator_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { "ignore.empty.value": ignoreEmptyValue = false, name: otherName, shouldBe, "error-message": errorMessageKey } = validator;
|
|
||||||
|
|
||||||
if (ignoreEmptyValue && value === "") {
|
|
||||||
break validator_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
const otherFieldValue = fieldValues.find(fieldValue => fieldValue.name === otherName);
|
|
||||||
|
|
||||||
assert(otherFieldValue !== undefined);
|
|
||||||
|
|
||||||
const isValid = (() => {
|
|
||||||
switch (shouldBe) {
|
|
||||||
case "different":
|
|
||||||
return otherFieldValue.value !== value;
|
|
||||||
case "equal":
|
|
||||||
return otherFieldValue.value === value;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
if (isValid) {
|
|
||||||
break validator_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
const msgArg = [
|
|
||||||
errorMessageKey ??
|
|
||||||
id<MessageKey>(
|
|
||||||
(() => {
|
|
||||||
switch (shouldBe) {
|
|
||||||
case "equal":
|
|
||||||
return "shouldBeEqual";
|
|
||||||
case "different":
|
|
||||||
return "shouldBeDifferent";
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
),
|
|
||||||
otherName,
|
|
||||||
name,
|
|
||||||
shouldBe
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
errors.push({
|
|
||||||
validatorName,
|
|
||||||
"errorMessage": <Fragment key={errors.length}>{advancedMsg(...msgArg)}</Fragment>,
|
|
||||||
"errorMessageStr": advancedMsgStr(...msgArg)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
validator_x: {
|
validator_x: {
|
||||||
const validatorName = "pattern";
|
const validatorName = "pattern";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user