[#6607] allowed manually changing the password from the create/update hooks
This commit is contained in:
parent
e49025c8e5
commit
201e2ccb05
|
@ -31,7 +31,7 @@
|
||||||
- Soft-deprecated the `$http.send`'s `result.raw` field in favor of `result.body` that contains the response body as plain bytes slice to avoid the discrepancies between Go and the JSVM when casting binary data to string.
|
- Soft-deprecated the `$http.send`'s `result.raw` field in favor of `result.body` that contains the response body as plain bytes slice to avoid the discrepancies between Go and the JSVM when casting binary data to string.
|
||||||
(@todo update docs to use the new field)
|
(@todo update docs to use the new field)
|
||||||
|
|
||||||
- Minor UI fixes (_removed the superuser fields from the auth record create/update body examples, etc._).
|
- Other minor improvements (_removed the superuser fields from the auth record create/update body examples, allowed programmatically updating the auth record password from the create/update hooks, etc._).
|
||||||
|
|
||||||
|
|
||||||
## v0.26.6
|
## v0.26.6
|
||||||
|
|
|
@ -27,6 +27,7 @@ type RecordUpsert struct {
|
||||||
accessLevel int
|
accessLevel int
|
||||||
|
|
||||||
// extra password fields
|
// extra password fields
|
||||||
|
disablePasswordValidations bool
|
||||||
password string
|
password string
|
||||||
passwordConfirm string
|
passwordConfirm string
|
||||||
oldPassword string
|
oldPassword string
|
||||||
|
@ -130,6 +131,8 @@ func (form *RecordUpsert) validateFormFields() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form.syncPasswordFields()
|
||||||
|
|
||||||
isNew := form.record.IsNew()
|
isNew := form.record.IsNew()
|
||||||
|
|
||||||
original := form.record.Original()
|
original := form.record.Original()
|
||||||
|
@ -165,17 +168,17 @@ func (form *RecordUpsert) validateFormFields() error {
|
||||||
validation.Key(
|
validation.Key(
|
||||||
"password",
|
"password",
|
||||||
validation.When(
|
validation.When(
|
||||||
(isNew || form.passwordConfirm != "" || form.oldPassword != ""),
|
!form.disablePasswordValidations && (isNew || form.passwordConfirm != "" || form.oldPassword != ""),
|
||||||
validation.Required,
|
validation.Required,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
validation.Key(
|
validation.Key(
|
||||||
"passwordConfirm",
|
"passwordConfirm",
|
||||||
validation.When(
|
validation.When(
|
||||||
(isNew || form.password != "" || form.oldPassword != ""),
|
!form.disablePasswordValidations && (isNew || form.password != "" || form.oldPassword != ""),
|
||||||
validation.Required,
|
validation.Required,
|
||||||
),
|
),
|
||||||
validation.By(validators.Equal(form.password)),
|
validation.When(!form.disablePasswordValidations, validation.By(validators.Equal(form.password))),
|
||||||
),
|
),
|
||||||
validation.Key(
|
validation.Key(
|
||||||
"oldPassword",
|
"oldPassword",
|
||||||
|
@ -183,7 +186,7 @@ func (form *RecordUpsert) validateFormFields() error {
|
||||||
// - form.HasManageAccess() is not satisfied
|
// - form.HasManageAccess() is not satisfied
|
||||||
// - changing the existing password
|
// - changing the existing password
|
||||||
validation.When(
|
validation.When(
|
||||||
!isNew && !form.HasManageAccess() && (form.password != "" || form.passwordConfirm != ""),
|
!form.disablePasswordValidations && !isNew && !form.HasManageAccess() && (form.password != "" || form.passwordConfirm != ""),
|
||||||
validation.Required,
|
validation.Required,
|
||||||
validation.By(form.checkOldPassword),
|
validation.By(form.checkOldPassword),
|
||||||
),
|
),
|
||||||
|
@ -287,3 +290,27 @@ func (form *RecordUpsert) Submit() error {
|
||||||
// run record validations and persist in db
|
// run record validations and persist in db
|
||||||
return form.app.SaveWithContext(form.ctx, form.record)
|
return form.app.SaveWithContext(form.ctx, form.record)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// syncPasswordFields syncs the form's auth password fields with their
|
||||||
|
// corresponding record field values.
|
||||||
|
//
|
||||||
|
// This could be useful in case the password fields were programmatically set
|
||||||
|
// directly by modifying the related record model.
|
||||||
|
func (form *RecordUpsert) syncPasswordFields() {
|
||||||
|
if !form.record.Collection().IsAuth() {
|
||||||
|
return // not an auth collection
|
||||||
|
}
|
||||||
|
|
||||||
|
form.disablePasswordValidations = false
|
||||||
|
|
||||||
|
rawPassword := form.record.GetRaw(core.FieldNamePassword)
|
||||||
|
if v, ok := rawPassword.(*core.PasswordFieldValue); ok && v != nil {
|
||||||
|
if
|
||||||
|
// programmatically set custom plain password value
|
||||||
|
(v.Plain != "" && v.Plain != form.password) ||
|
||||||
|
// random generated password for new record
|
||||||
|
(v.Plain == "" && v.Hash != "" && form.record.IsNew()) {
|
||||||
|
form.disablePasswordValidations = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -887,6 +887,119 @@ func TestRecordUpsertSubmitSuccess(t *testing.T) {
|
||||||
testFilesCount(t, testApp, record, 2) // the file + attrs
|
testFilesCount(t, testApp, record, 2) // the file + attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRecordUpsertPasswordsSync(t *testing.T) {
|
||||||
|
testApp, _ := tests.NewTestApp()
|
||||||
|
defer testApp.Cleanup()
|
||||||
|
|
||||||
|
users, err := testApp.FindCollectionByNameOrId("users")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("new user without password", func(t *testing.T) {
|
||||||
|
record := core.NewRecord(users)
|
||||||
|
|
||||||
|
form := forms.NewRecordUpsert(testApp, record)
|
||||||
|
|
||||||
|
err := form.Submit()
|
||||||
|
|
||||||
|
tests.TestValidationErrors(t, err, []string{"password", "passwordConfirm"})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("new user with manual password", func(t *testing.T) {
|
||||||
|
record := core.NewRecord(users)
|
||||||
|
|
||||||
|
form := forms.NewRecordUpsert(testApp, record)
|
||||||
|
|
||||||
|
record.SetPassword("1234567890")
|
||||||
|
|
||||||
|
err := form.Submit()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no errors, got %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("new user with random password", func(t *testing.T) {
|
||||||
|
record := core.NewRecord(users)
|
||||||
|
|
||||||
|
form := forms.NewRecordUpsert(testApp, record)
|
||||||
|
|
||||||
|
record.SetRandomPassword()
|
||||||
|
|
||||||
|
err := form.Submit()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no errors, got %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("update user with no password change", func(t *testing.T) {
|
||||||
|
record, err := testApp.FindAuthRecordByEmail(users, "test@example.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldHash := record.GetString("password:hash")
|
||||||
|
|
||||||
|
form := forms.NewRecordUpsert(testApp, record)
|
||||||
|
|
||||||
|
err = form.Submit()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no errors, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newHash := record.GetString("password:hash")
|
||||||
|
if newHash == "" || newHash != oldHash {
|
||||||
|
t.Fatal("Expected no password change")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("update user with manual password change", func(t *testing.T) {
|
||||||
|
record, err := testApp.FindAuthRecordByEmail(users, "test@example.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldHash := record.GetString("password:hash")
|
||||||
|
|
||||||
|
form := forms.NewRecordUpsert(testApp, record)
|
||||||
|
|
||||||
|
record.SetPassword("1234567890")
|
||||||
|
|
||||||
|
err = form.Submit()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no errors, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newHash := record.GetString("password:hash")
|
||||||
|
if newHash == "" || newHash == oldHash {
|
||||||
|
t.Fatal("Expected password change")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("update user with random password change", func(t *testing.T) {
|
||||||
|
record, err := testApp.FindAuthRecordByEmail(users, "test@example.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldHash := record.GetString("password:hash")
|
||||||
|
|
||||||
|
form := forms.NewRecordUpsert(testApp, record)
|
||||||
|
|
||||||
|
record.SetRandomPassword()
|
||||||
|
|
||||||
|
err = form.Submit()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no errors, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newHash := record.GetString("password:hash")
|
||||||
|
if newHash == "" || newHash == oldHash {
|
||||||
|
t.Fatal("Expected password change")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
func testFilesCount(t *testing.T, app core.App, record *core.Record, count int) {
|
func testFilesCount(t *testing.T, app core.App, record *core.Record, count int) {
|
||||||
|
|
Loading…
Reference in New Issue