@@ -14,6 +14,7 @@ import {
14
14
useFormModified ,
15
15
useTranslation ,
16
16
} from '@payloadcms/ui'
17
+ import { email as emailValidation } from 'payload/shared'
17
18
import React , { useCallback , useEffect , useMemo , useState } from 'react'
18
19
import { toast } from 'sonner'
19
20
@@ -34,6 +35,8 @@ export const Auth: React.FC<Props> = (props) => {
34
35
operation,
35
36
readOnly,
36
37
requirePassword,
38
+ setSchemaPath,
39
+ setValidateBeforeSubmit,
37
40
useAPIKey,
38
41
username,
39
42
verify,
@@ -42,6 +45,7 @@ export const Auth: React.FC<Props> = (props) => {
42
45
const { permissions } = useAuth ( )
43
46
const [ changingPassword , setChangingPassword ] = useState ( requirePassword )
44
47
const enableAPIKey = useFormFields ( ( [ fields ] ) => ( fields && fields ?. enableAPIKey ) || null )
48
+ const forceOpenChangePassword = useFormFields ( ( [ fields ] ) => ( fields && fields ?. password ) || null )
45
49
const dispatchFields = useFormFields ( ( reducer ) => reducer [ 1 ] )
46
50
const modified = useFormModified ( )
47
51
const { i18n, t } = useTranslation ( )
@@ -70,15 +74,32 @@ export const Auth: React.FC<Props> = (props) => {
70
74
} , [ permissions , collectionSlug ] )
71
75
72
76
const handleChangePassword = useCallback (
73
- ( state : boolean ) => {
74
- if ( ! state ) {
77
+ ( showPasswordFields : boolean ) => {
78
+ if ( showPasswordFields ) {
79
+ setValidateBeforeSubmit ( true )
80
+ setSchemaPath ( `_${ collectionSlug } .auth` )
81
+ dispatchFields ( {
82
+ type : 'UPDATE' ,
83
+ errorMessage : t ( 'validation:required' ) ,
84
+ path : 'password' ,
85
+ valid : false ,
86
+ } )
87
+ dispatchFields ( {
88
+ type : 'UPDATE' ,
89
+ errorMessage : t ( 'validation:required' ) ,
90
+ path : 'confirm-password' ,
91
+ valid : false ,
92
+ } )
93
+ } else {
94
+ setValidateBeforeSubmit ( false )
95
+ setSchemaPath ( collectionSlug )
75
96
dispatchFields ( { type : 'REMOVE' , path : 'password' } )
76
97
dispatchFields ( { type : 'REMOVE' , path : 'confirm-password' } )
77
98
}
78
99
79
- setChangingPassword ( state )
100
+ setChangingPassword ( showPasswordFields )
80
101
} ,
81
- [ dispatchFields ] ,
102
+ [ dispatchFields , t , collectionSlug , setSchemaPath , setValidateBeforeSubmit ] ,
82
103
)
83
104
84
105
const unlock = useCallback ( async ( ) => {
@@ -99,7 +120,7 @@ export const Auth: React.FC<Props> = (props) => {
99
120
} else {
100
121
toast . error ( t ( 'authentication:failedToUnlock' ) )
101
122
}
102
- } , [ i18n , serverURL , api , collectionSlug , email , username , t ] )
123
+ } , [ i18n , serverURL , api , collectionSlug , email , username , t , loginWithUsername ] )
103
124
104
125
useEffect ( ( ) => {
105
126
if ( ! modified ) {
@@ -113,6 +134,8 @@ export const Auth: React.FC<Props> = (props) => {
113
134
114
135
const disabled = readOnly || isInitializing
115
136
137
+ const showPasswordFields = changingPassword || forceOpenChangePassword
138
+
116
139
return (
117
140
< div className = { [ baseClass , className ] . filter ( Boolean ) . join ( ' ' ) } >
118
141
{ ! disableLocalStrategy && (
@@ -136,22 +159,33 @@ export const Auth: React.FC<Props> = (props) => {
136
159
name = "email"
137
160
readOnly = { readOnly }
138
161
required = { ! loginWithUsername || loginWithUsername ?. requireEmail }
162
+ validate = { ( value ) =>
163
+ emailValidation ( value , {
164
+ name : 'email' ,
165
+ type : 'email' ,
166
+ data : { } ,
167
+ preferences : { fields : { } } ,
168
+ req : { t } as any ,
169
+ required : true ,
170
+ siblingData : { } ,
171
+ } )
172
+ }
139
173
/>
140
174
) }
141
- { ( changingPassword || requirePassword ) && (
175
+ { ( showPasswordFields || requirePassword ) && (
142
176
< div className = { `${ baseClass } __changing-password` } >
143
177
< PasswordField
144
- autoComplete = "off"
145
178
disabled = { disabled }
146
179
label = { t ( 'authentication:newPassword' ) }
147
180
name = "password"
181
+ path = "password"
148
182
required
149
183
/>
150
184
< ConfirmPasswordField disabled = { readOnly } />
151
185
</ div >
152
186
) }
153
187
< div className = { `${ baseClass } __controls` } >
154
- { changingPassword && ! requirePassword && (
188
+ { showPasswordFields && ! requirePassword && (
155
189
< Button
156
190
buttonStyle = "secondary"
157
191
disabled = { disabled }
@@ -161,7 +195,7 @@ export const Auth: React.FC<Props> = (props) => {
161
195
{ t ( 'general:cancel' ) }
162
196
</ Button >
163
197
) }
164
- { ! changingPassword && ! requirePassword && (
198
+ { ! showPasswordFields && ! requirePassword && (
165
199
< Button
166
200
buttonStyle = "secondary"
167
201
disabled = { disabled }
0 commit comments