forked from mirrors/pronouns.cc
fix: validate member name contents
This commit is contained in:
parent
fe0680d587
commit
d223cd89e8
4 changed files with 53 additions and 1 deletions
|
@ -2,6 +2,7 @@ package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"emperror.dev/errors"
|
"emperror.dev/errors"
|
||||||
"github.com/georgysavva/scany/pgxscan"
|
"github.com/georgysavva/scany/pgxscan"
|
||||||
|
@ -32,6 +33,13 @@ const (
|
||||||
ErrMemberNameInUse = errors.Sentinel("member name already in use")
|
ErrMemberNameInUse = errors.Sentinel("member name already in use")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// member names must match this regex
|
||||||
|
var memberNameRegex = regexp.MustCompile("^[^@\\?!#/\\\\[\\]\"'$%&()+<=>^|~`,]{1,100}$")
|
||||||
|
|
||||||
|
func MemberNameValid(name string) bool {
|
||||||
|
return memberNameRegex.MatchString(name)
|
||||||
|
}
|
||||||
|
|
||||||
func (db *DB) Member(ctx context.Context, id xid.ID) (m Member, err error) {
|
func (db *DB) Member(ctx context.Context, id xid.ID) (m Member, err error) {
|
||||||
sql, args, err := sq.Select("*").From("members").Where("id = ?", id).ToSql()
|
sql, args, err := sq.Select("*").From("members").Where("id = ?", id).ToSql()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package member
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
||||||
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
||||||
|
@ -51,6 +52,13 @@ func (s *Server) createMember(w http.ResponseWriter, r *http.Request) (err error
|
||||||
return server.APIError{Code: server.ErrBadRequest}
|
return server.APIError{Code: server.ErrBadRequest}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove whitespace from all fields
|
||||||
|
cmr.Name = strings.TrimSpace(cmr.Name)
|
||||||
|
cmr.Bio = strings.TrimSpace(cmr.Bio)
|
||||||
|
if cmr.DisplayName != nil {
|
||||||
|
*cmr.DisplayName = strings.TrimSpace(*cmr.DisplayName)
|
||||||
|
}
|
||||||
|
|
||||||
// validate everything
|
// validate everything
|
||||||
if cmr.Name == "" {
|
if cmr.Name == "" {
|
||||||
return server.APIError{
|
return server.APIError{
|
||||||
|
@ -64,6 +72,13 @@ func (s *Server) createMember(w http.ResponseWriter, r *http.Request) (err error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !db.MemberNameValid(cmr.Name) {
|
||||||
|
return server.APIError{
|
||||||
|
Code: server.ErrBadRequest,
|
||||||
|
Details: "Member name cannot contain any of the following: @, \\, ?, !, #, /, \\, [, ], \", ', $, %, &, (, ), +, <, =, >, ^, |, ~, `, ,",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := validateSlicePtr("name", &cmr.Names); err != nil {
|
if err := validateSlicePtr("name", &cmr.Names); err != nil {
|
||||||
return *err
|
return *err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package member
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
||||||
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
||||||
|
@ -68,11 +69,37 @@ func (s *Server) patchMember(w http.ResponseWriter, r *http.Request) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trim whitespace from strings
|
||||||
|
if req.Name != nil {
|
||||||
|
*req.Name = strings.TrimSpace(*req.Name)
|
||||||
|
}
|
||||||
|
if req.DisplayName != nil {
|
||||||
|
*req.DisplayName = strings.TrimSpace(*req.Name)
|
||||||
|
}
|
||||||
|
if req.Bio != nil {
|
||||||
|
*req.Bio = strings.TrimSpace(*req.Bio)
|
||||||
|
}
|
||||||
|
|
||||||
if req.Name != nil && *req.Name == "" {
|
if req.Name != nil && *req.Name == "" {
|
||||||
return server.APIError{
|
return server.APIError{
|
||||||
Code: server.ErrBadRequest,
|
Code: server.ErrBadRequest,
|
||||||
Details: "Name must not be empty",
|
Details: "Name must not be empty",
|
||||||
}
|
}
|
||||||
|
} else if req.Name != nil && len(*req.Name) > 100 {
|
||||||
|
return server.APIError{
|
||||||
|
Code: server.ErrBadRequest,
|
||||||
|
Details: "Name may not be longer than 100 characters",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate member name
|
||||||
|
if req.Name != nil {
|
||||||
|
if !db.MemberNameValid(*req.Name) {
|
||||||
|
return server.APIError{
|
||||||
|
Code: server.ErrBadRequest,
|
||||||
|
Details: "Member name cannot contain any of the following: @, \\, ?, !, #, /, \\, [, ], \", ', $, %, &, (, ), +, <, =, >, ^, |, ~, `, ,",
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate display name/bio
|
// validate display name/bio
|
||||||
|
|
|
@ -61,11 +61,12 @@
|
||||||
|
|
||||||
let modified = false;
|
let modified = false;
|
||||||
|
|
||||||
$: modified = isModified(bio, display_name, links, names, pronouns, fields, avatar);
|
$: modified = isModified(bio, name, display_name, links, names, pronouns, fields, avatar);
|
||||||
$: getAvatar(avatar_files).then((b64) => (avatar = b64));
|
$: getAvatar(avatar_files).then((b64) => (avatar = b64));
|
||||||
|
|
||||||
const isModified = (
|
const isModified = (
|
||||||
bio: string,
|
bio: string,
|
||||||
|
name: string,
|
||||||
display_name: string,
|
display_name: string,
|
||||||
links: string[],
|
links: string[],
|
||||||
names: FieldEntry[],
|
names: FieldEntry[],
|
||||||
|
@ -73,6 +74,7 @@
|
||||||
fields: Field[],
|
fields: Field[],
|
||||||
avatar: string | null,
|
avatar: string | null,
|
||||||
) => {
|
) => {
|
||||||
|
if (name !== data.member.name) return true;
|
||||||
if (bio !== data.member.bio) return true;
|
if (bio !== data.member.bio) return true;
|
||||||
if (display_name !== data.member.display_name) return true;
|
if (display_name !== data.member.display_name) return true;
|
||||||
if (!linksEqual(links, data.member.links)) return true;
|
if (!linksEqual(links, data.member.links)) return true;
|
||||||
|
|
Loading…
Reference in a new issue