Similar to the profile form, the login form now parses and validates itself, with the InputField structs that the templates expect. I realized that i was doing more work than necessary when parsing fields fro the profile form because i was repeating the operation and the field name, so now it is a function of InputField. This time i needed extra attributes for the login form. I am not sure that the Go source code needs to know about HTML attributes, but it was the easiest way to pass them to the template.
131 lines
3.9 KiB
Go
131 lines
3.9 KiB
Go
package pkg
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
)
|
|
|
|
type LanguageOption struct {
|
|
Tag string
|
|
Name string
|
|
}
|
|
|
|
type profileForm struct {
|
|
locale *Locale
|
|
Name *InputField
|
|
Email *InputField
|
|
Password *InputField
|
|
PasswordConfirm *InputField
|
|
Language *SelectField
|
|
Valid bool
|
|
}
|
|
|
|
func newProfileForm(ctx context.Context, conn *Conn, locale *Locale) *profileForm {
|
|
automaticOption := pgettext("language option", "Automatic", locale)
|
|
languages := MustGetOptions(ctx, conn, "select 'und', $1 union all select lang_tag, endonym from language where selectable", automaticOption)
|
|
return &profileForm{
|
|
locale: locale,
|
|
Name: &InputField{
|
|
Name: "name",
|
|
Label: pgettext("input", "User name", locale),
|
|
Type: "text",
|
|
Required: true,
|
|
},
|
|
Email: &InputField{
|
|
Name: "email",
|
|
Label: pgettext("input", "Email", locale),
|
|
Type: "email",
|
|
Required: true,
|
|
},
|
|
Password: &InputField{
|
|
Name: "password",
|
|
Label: pgettext("input", "Password", locale),
|
|
Type: "password",
|
|
},
|
|
PasswordConfirm: &InputField{
|
|
Name: "password_confirm",
|
|
Label: pgettext("input", "Password Confirmation", locale),
|
|
Type: "password",
|
|
},
|
|
Language: &SelectField{
|
|
Name: "language",
|
|
Label: pgettext("input", "Language", locale),
|
|
Options: languages,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (form *profileForm) Parse(r *http.Request) error {
|
|
if err := r.ParseForm(); err != nil {
|
|
return err
|
|
}
|
|
form.Email.FillValue(r)
|
|
form.Name.FillValue(r)
|
|
form.Password.FillValue(r)
|
|
form.PasswordConfirm.FillValue(r)
|
|
form.Language.FillValue(r)
|
|
return nil
|
|
}
|
|
|
|
func (form *profileForm) Validate() bool {
|
|
form.Valid = true
|
|
if form.Email.IsEmpty() {
|
|
form.AppendInputError(form.Email, errors.New(gettext("Email can not be empty.", form.locale)))
|
|
} else if !form.Email.HasValidEmail() {
|
|
form.AppendInputError(form.Email, errors.New(gettext("This value is not a valid email. It should be like name@domain.com.", form.locale)))
|
|
}
|
|
if form.Name.IsEmpty() {
|
|
form.AppendInputError(form.Name, errors.New(gettext("Name can not be empty.", form.locale)))
|
|
}
|
|
if !form.PasswordConfirm.Equals(form.Password) {
|
|
form.AppendInputError(form.PasswordConfirm, errors.New(gettext("Confirmation does not match password.", form.locale)))
|
|
}
|
|
if !form.Language.HasValidOption() {
|
|
form.AppendSelectError(form.Language, errors.New(gettext("Selected language is not valid.", form.locale)))
|
|
}
|
|
return form.Valid
|
|
}
|
|
|
|
func (form *profileForm) AppendInputError(field *InputField, err error) {
|
|
field.Errors = append(field.Errors, err)
|
|
form.Valid = false
|
|
}
|
|
|
|
func (form *profileForm) AppendSelectError(field *SelectField, err error) {
|
|
field.Errors = append(field.Errors, err)
|
|
form.Valid = false
|
|
}
|
|
|
|
func ProfileHandler() http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
user := getUser(r)
|
|
conn := getConn(r)
|
|
locale := getLocale(r)
|
|
form := newProfileForm(r.Context(), conn, locale)
|
|
if r.Method == "POST" {
|
|
if err := form.Parse(r); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
if ok := form.Validate(); ok {
|
|
//goland:noinspection SqlWithoutWhere
|
|
cookie := conn.MustGetText(r.Context(), "", "update user_profile set name = $1, email = $2, lang_tag = $3 returning build_cookie()", form.Name.Value, form.Email.Value, form.Language.Selected)
|
|
setSessionCookie(w, cookie)
|
|
if form.Password.Value != "" {
|
|
conn.MustExec(r.Context(), "select change_password($1)", form.Password.Value)
|
|
}
|
|
company := getCompany(r)
|
|
http.Redirect(w, r, "/company/"+company.Slug+"/profile", http.StatusSeeOther)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusUnprocessableEntity)
|
|
} else {
|
|
form.Name.Value = conn.MustGetText(r.Context(), "", "select name from user_profile")
|
|
form.Email.Value = user.Email
|
|
form.Language.Selected = user.Language.String()
|
|
}
|
|
mustRenderAppTemplate(w, r, "profile.gohtml", form)
|
|
})
|
|
}
|