diff --git a/backend/db/avatars.go b/backend/db/avatars.go index f35ef26..e59c682 100644 --- a/backend/db/avatars.go +++ b/backend/db/avatars.go @@ -19,6 +19,7 @@ import ( const ErrInvalidDataURI = errors.Sentinel("invalid data URI") const ErrInvalidContentType = errors.Sentinel("invalid avatar content type") +const ErrFileTooLarge = errors.Sentinel("file to be converted exceeds maximum size") // ConvertAvatar parses an avatar from a data URI, converts it to WebP and JPEG, and returns the results. func (db *DB) ConvertAvatar(data string) ( diff --git a/backend/db/flags.go b/backend/db/flags.go index 6f3458b..94e70ea 100644 --- a/backend/db/flags.go +++ b/backend/db/flags.go @@ -59,7 +59,7 @@ const ( ) func (db *DB) AccountFlags(ctx context.Context, userID xid.ID) (fs []PrideFlag, err error) { - sql, args, err := sq.Select("*").From("pride_flags").Where("user_id = ?", userID).OrderBy("id").ToSql() + sql, args, err := sq.Select("*").From("pride_flags").Where("user_id = ?", userID).OrderBy("lower(name)").ToSql() if err != nil { return nil, errors.Wrap(err, "building query") } @@ -285,6 +285,8 @@ func (db *DB) FlagObject(ctx context.Context, flagID xid.ID, hash string) (io.Re return obj, nil } +const MaxFlagInputSize = 512_000 + // ConvertFlag parses a flag from a data URI, converts it to WebP, and returns the result. func (db *DB) ConvertFlag(data string) (webpOut *bytes.Buffer, err error) { defer vips.ShutdownThread() @@ -300,6 +302,10 @@ func (db *DB) ConvertFlag(data string) (webpOut *bytes.Buffer, err error) { return nil, errors.Wrap(err, "invalid base64 data") } + if len(rawData) > MaxFlagInputSize { + return nil, ErrFileTooLarge + } + image, err := vips.LoadImageFromBuffer(rawData, nil) if err != nil { return nil, errors.Wrap(err, "decoding image") diff --git a/backend/routes/user/flags.go b/backend/routes/user/flags.go index 77654f3..60219b9 100644 --- a/backend/routes/user/flags.go +++ b/backend/routes/user/flags.go @@ -91,6 +91,8 @@ func (s *Server) postUserFlag(w http.ResponseWriter, r *http.Request) error { if err != nil { if err == db.ErrInvalidDataURI { return server.APIError{Code: server.ErrBadRequest, Message: "invalid data URI"} + } else if err == db.ErrFileTooLarge { + return server.APIError{Code: server.ErrBadRequest, Message: "data URI exceeds 512 KB"} } return errors.Wrap(err, "converting flag") } diff --git a/frontend/src/lib/api/entities.ts b/frontend/src/lib/api/entities.ts index acb2767..df2ad47 100644 --- a/frontend/src/lib/api/entities.ts +++ b/frontend/src/lib/api/entities.ts @@ -96,6 +96,13 @@ export interface MemberPartialUser { custom_preferences: CustomPreferences; } +export interface PrideFlag { + id: string; + hash: string; + name: string; + description: string | null; +} + export interface Invite { code: string; created: string; @@ -192,6 +199,8 @@ export const memberAvatars = (member: Member | PartialMember) => { ]; }; +export const flagURL = ({ hash }: PrideFlag) => `${PUBLIC_MEDIA_URL}/flags/${hash}.webp`; + export const defaultAvatars = [ `${PUBLIC_BASE_URL}/default/512.webp`, `${PUBLIC_BASE_URL}/default/512.jpg`, diff --git a/frontend/src/routes/settings/+layout.svelte b/frontend/src/routes/settings/+layout.svelte index 785c43b..4e66453 100644 --- a/frontend/src/routes/settings/+layout.svelte +++ b/frontend/src/routes/settings/+layout.svelte @@ -42,20 +42,13 @@
+ You can upload pride flags to use on your profiles here. Flags you upload here will not automatically + show up on your profile. +
+ +
+
+ + +
+
+
+ + +
+
+