feat: count characters consistently
This commit is contained in:
parent
80ca1cae00
commit
8433a1523a
|
@ -0,0 +1,11 @@
|
|||
// Package common contains functions and types common to all (or most) packages.
|
||||
package common
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
func StringLength(s *string) int {
|
||||
if s == nil {
|
||||
return -1
|
||||
}
|
||||
return utf8.RuneCountInString(*s)
|
||||
}
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/common"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/server"
|
||||
|
@ -83,6 +84,25 @@ func (s *Server) createMember(w http.ResponseWriter, r *http.Request) (err error
|
|||
}
|
||||
}
|
||||
|
||||
if common.StringLength(&cmr.Name) > db.MaxMemberNameLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Name name too long (max %d, current %d)", db.MaxMemberNameLength, common.StringLength(&cmr.Name)),
|
||||
}
|
||||
}
|
||||
if common.StringLength(cmr.DisplayName) > db.MaxDisplayNameLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Display name too long (max %d, current %d)", db.MaxDisplayNameLength, common.StringLength(cmr.DisplayName)),
|
||||
}
|
||||
}
|
||||
if common.StringLength(&cmr.Bio) > db.MaxUserBioLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Bio too long (max %d, current %d)", db.MaxUserBioLength, common.StringLength(&cmr.Bio)),
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateSlicePtr("name", &cmr.Names); err != nil {
|
||||
return *err
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/common"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/server"
|
||||
|
@ -109,22 +110,22 @@ func (s *Server) patchMember(w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
// validate display name/bio
|
||||
if req.Name != nil && len(*req.Name) > db.MaxMemberNameLength {
|
||||
if common.StringLength(req.Name) > db.MaxMemberNameLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Name name too long (max %d, current %d)", db.MaxMemberNameLength, len(*req.Name)),
|
||||
Details: fmt.Sprintf("Name name too long (max %d, current %d)", db.MaxMemberNameLength, common.StringLength(req.Name)),
|
||||
}
|
||||
}
|
||||
if req.DisplayName != nil && len(*req.DisplayName) > db.MaxDisplayNameLength {
|
||||
if common.StringLength(req.DisplayName) > db.MaxDisplayNameLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Display name too long (max %d, current %d)", db.MaxDisplayNameLength, len(*req.DisplayName)),
|
||||
Details: fmt.Sprintf("Display name too long (max %d, current %d)", db.MaxDisplayNameLength, common.StringLength(req.DisplayName)),
|
||||
}
|
||||
}
|
||||
if req.Bio != nil && len(*req.Bio) > db.MaxUserBioLength {
|
||||
if common.StringLength(req.Bio) > db.MaxUserBioLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Bio too long (max %d, current %d)", db.MaxUserBioLength, len(*req.Bio)),
|
||||
Details: fmt.Sprintf("Bio too long (max %d, current %d)", db.MaxUserBioLength, common.StringLength(req.Name)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/common"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/server"
|
||||
|
@ -64,23 +65,22 @@ func (s *Server) patchUser(w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
// validate display name/bio
|
||||
if req.DisplayName != nil && len(*req.DisplayName) > db.MaxDisplayNameLength {
|
||||
if common.StringLength(req.Username) > db.MaxUsernameLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Display name too long (max %d, current %d)", db.MaxDisplayNameLength, len(*req.DisplayName)),
|
||||
Details: fmt.Sprintf("Name name too long (max %d, current %d)", db.MaxUsernameLength, common.StringLength(req.Username)),
|
||||
}
|
||||
}
|
||||
if req.Bio != nil && len(*req.Bio) > db.MaxUserBioLength {
|
||||
if common.StringLength(req.DisplayName) > db.MaxDisplayNameLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Bio too long (max %d, current %d)", db.MaxUserBioLength, len(*req.Bio)),
|
||||
Details: fmt.Sprintf("Display name too long (max %d, current %d)", db.MaxDisplayNameLength, common.StringLength(req.DisplayName)),
|
||||
}
|
||||
}
|
||||
// this is considered a name
|
||||
if req.MemberTitle != nil && len(*req.MemberTitle) > db.MaxDisplayNameLength {
|
||||
if common.StringLength(req.Bio) > db.MaxUserBioLength {
|
||||
return server.APIError{
|
||||
Code: server.ErrBadRequest,
|
||||
Details: fmt.Sprintf("Member title too long (max %d, current %d)", db.MaxDisplayNameLength, len(*req.MemberTitle)),
|
||||
Details: fmt.Sprintf("Bio too long (max %d, current %d)", db.MaxUserBioLength, common.StringLength(req.Bio)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ const md = new MarkdownIt({
|
|||
breaks: true,
|
||||
}).disable(["heading", "link", "table"]);
|
||||
|
||||
export default function renderMarkdown(src: string | null) {
|
||||
export function renderMarkdown(src: string | null) {
|
||||
return src ? sanitize(md.render(src)) : null;
|
||||
}
|
||||
|
||||
export const charCount = (str: string) => [...str].length;
|
|
@ -30,7 +30,7 @@
|
|||
import { apiFetchClient } from "$lib/api/fetch";
|
||||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||
import { goto } from "$app/navigation";
|
||||
import renderMarkdown from "$lib/api/markdown";
|
||||
import {renderMarkdown} from "$lib/utils"
|
||||
import ReportButton from "./ReportButton.svelte";
|
||||
import ProfileLink from "./ProfileLink.svelte";
|
||||
import { memberNameRegex } from "$lib/api/regex";
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { memberAvatars, pronounDisplay, WordStatus } from "$lib/api/entities";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import { userStore } from "$lib/store";
|
||||
import renderMarkdown from "$lib/api/markdown";
|
||||
import { renderMarkdown } from "$lib/utils";
|
||||
import ReportButton from "../ReportButton.svelte";
|
||||
import ProfileLink from "../ProfileLink.svelte";
|
||||
import StatusLine from "$lib/components/StatusLine.svelte";
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
import type { PageData } from "./$types";
|
||||
import { addToast, delToast } from "$lib/toast";
|
||||
import { memberNameRegex } from "$lib/api/regex";
|
||||
import renderMarkdown from "$lib/api/markdown";
|
||||
import { charCount, renderMarkdown } from "$lib/utils";
|
||||
|
||||
const MAX_AVATAR_BYTES = 1_000_000;
|
||||
|
||||
|
@ -445,7 +445,7 @@
|
|||
<textarea class="form-control" style="height: 200px;" bind:value={bio} />
|
||||
</div>
|
||||
<p class="text-muted mt-1">
|
||||
Using {bio.length}/{MAX_DESCRIPTION_LENGTH} characters
|
||||
Using {charCount(bio)}/{MAX_DESCRIPTION_LENGTH} characters
|
||||
</p>
|
||||
<p class="text-muted my-2">
|
||||
<Icon name="info-circle-fill" aria-hidden /> Your bio supports limited
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
|
||||
import { addToast, delToast } from "$lib/toast";
|
||||
import type { PageData } from "./$types";
|
||||
import renderMarkdown from "$lib/api/markdown";
|
||||
import { charCount, renderMarkdown } from "$lib/utils";
|
||||
|
||||
const MAX_AVATAR_BYTES = 1_000_000;
|
||||
|
||||
|
@ -373,7 +373,7 @@
|
|||
<textarea class="form-control" style="height: 200px;" bind:value={bio} />
|
||||
</div>
|
||||
<p class="text-muted mt-1">
|
||||
Using {bio.length}/{MAX_DESCRIPTION_LENGTH} characters
|
||||
Using {charCount(bio)}/{MAX_DESCRIPTION_LENGTH} characters
|
||||
</p>
|
||||
<p class="text-muted my-2">
|
||||
<Icon name="info-circle-fill" aria-hidden /> Your bio supports limited
|
||||
|
|
Loading…
Reference in New Issue