From 1134128a71bf5fee6fdc6096406d67b1833e1d16 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sat, 29 Jun 2024 21:42:35 -0700 Subject: [PATCH] Revert "Public Avatar Consent Page" This reverts commit 4f04323d5a2a8afae35aa3ae4d0376b31f7ce12a. --- pkg/config/config.go | 9 - pkg/config/enum.go | 3 +- .../account/public_avatar_consent.go | 55 ---- pkg/controller/chat/chat.go | 16 +- pkg/middleware/authentication.go | 5 - pkg/middleware/public_avatar_consent.go | 31 -- pkg/models/shy_accounts.go | 37 +-- pkg/models/user.go | 6 +- pkg/models/user_relationship.go | 21 +- pkg/router/router.go | 1 - pkg/templates/template_vars.go | 3 - .../account/public_avatar_consent.html | 296 ------------------ web/templates/account/settings.html | 9 - web/templates/partials/user_avatar.html | 30 +- 14 files changed, 29 insertions(+), 493 deletions(-) delete mode 100644 pkg/controller/account/public_avatar_consent.go delete mode 100644 pkg/middleware/public_avatar_consent.go delete mode 100644 web/templates/account/public_avatar_consent.html diff --git a/pkg/config/config.go b/pkg/config/config.go index 5ce6b04..7bf1235 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -118,15 +118,6 @@ const ( SiteGalleryRateLimitInterval = 24 * time.Hour ) -// Profile photo "public square cropped version" migration controls. -// Previously: a Private or Friends-only profile picture would show a placeholder avatar to users -// who couldn't see the full size version. In migration, these square cropped images will move to -// be always public (the full-size versions can remain private). -// NOTE: search code base for PublicAvatar or "public avatar" for related feature code. -var ( - PublicAvatarEnforcementDate = time.Date(2024, time.August, 30, 12, 0, 0, 0, time.UTC) -) - // Forum settings const ( // Only ++ the Views count per user per thread within a small diff --git a/pkg/config/enum.go b/pkg/config/enum.go index ac447c2..2fa7c4b 100644 --- a/pkg/config/enum.go +++ b/pkg/config/enum.go @@ -78,8 +78,7 @@ var ( SitePreferenceFields = []string{ "dm_privacy", "blur_explicit", - "site_gallery_default", // default view on site gallery (friends-only or all certified?) - "public_avatar_consent", // Public Avatars consent agreement + "site_gallery_default", // default view on site gallery (friends-only or all certified?) } // Choices for the Contact Us subject diff --git a/pkg/controller/account/public_avatar_consent.go b/pkg/controller/account/public_avatar_consent.go deleted file mode 100644 index 7bcc7f6..0000000 --- a/pkg/controller/account/public_avatar_consent.go +++ /dev/null @@ -1,55 +0,0 @@ -package account - -import ( - "net/http" - "strings" - - "code.nonshy.com/nonshy/website/pkg/session" - "code.nonshy.com/nonshy/website/pkg/templates" -) - -// Public avatar consent page (/settings/public-avatar-consent) -func PublicAvatarConsent() http.HandlerFunc { - tmpl := templates.Must("account/public_avatar_consent.html") - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - var next = r.FormValue("next") - if !strings.HasPrefix(next, "/") { - next = "/me" - } - vars := map[string]interface{}{ - "NextURL": next, - } - - // Load the current user in case of updates. - currentUser, err := session.CurrentUser(r) - if err != nil { - session.FlashError(w, r, "Couldn't get CurrentUser: %s", err) - templates.Redirect(w, r.URL.Path) - return - } - - // Are we POSTing? - if r.Method == http.MethodPost { - var ( - accept = r.PostFormValue("accept") - ) - - currentUser.SetProfileField("public_avatar_consent", accept) - - if accept == "true" { - session.Flash(w, r, "Thank you for agreeing to the Public Avatar policy! You may revisit this option from your Account Settings page in the future.") - templates.Redirect(w, next) - return - } - - session.Flash(w, r, "We have noted your non-consent to this change. Your avatar image (if non-public) will show as a placeholder avatar to people who don't have permission to see the full-size photo.") - templates.Redirect(w, r.URL.Path) - return - } - - if err := tmpl.Execute(w, r, vars); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - }) -} diff --git a/pkg/controller/chat/chat.go b/pkg/controller/chat/chat.go index 043f671..ca5f5c5 100644 --- a/pkg/controller/chat/chat.go +++ b/pkg/controller/chat/chat.go @@ -99,15 +99,13 @@ func Landing() http.HandlerFunc { // Avatar URL - masked if non-public. avatar := photo.URLPath(currentUser.ProfilePhoto.CroppedFilename) - if currentUser.GetProfileField("public_avatar_consent") != "true" { - switch currentUser.ProfilePhoto.Visibility { - case models.PhotoPrivate: - avatar = "/static/img/shy-private.png" - case models.PhotoFriends: - avatar = "/static/img/shy-friends.png" - case models.PhotoInnerCircle: - avatar = "/static/img/shy-secret.png" - } + switch currentUser.ProfilePhoto.Visibility { + case models.PhotoPrivate: + avatar = "/static/img/shy-private.png" + case models.PhotoFriends: + avatar = "/static/img/shy-friends.png" + case models.PhotoInnerCircle: + avatar = "/static/img/shy-secret.png" } // Country flag emoji. diff --git a/pkg/middleware/authentication.go b/pkg/middleware/authentication.go index c0c7421..6c33f5f 100644 --- a/pkg/middleware/authentication.go +++ b/pkg/middleware/authentication.go @@ -157,11 +157,6 @@ func CertRequired(handler http.Handler) http.Handler { return } - // Public Avatar consent enforcement? - if PublicAvatarConsent(currentUser, w, r) { - return - } - handler.ServeHTTP(w, r) }) } diff --git a/pkg/middleware/public_avatar_consent.go b/pkg/middleware/public_avatar_consent.go deleted file mode 100644 index e05ff77..0000000 --- a/pkg/middleware/public_avatar_consent.go +++ /dev/null @@ -1,31 +0,0 @@ -package middleware - -import ( - "net/http" - "net/url" - "time" - - "code.nonshy.com/nonshy/website/pkg/config" - "code.nonshy.com/nonshy/website/pkg/models" - "code.nonshy.com/nonshy/website/pkg/templates" -) - -// PublicAvatarConsent: part of CertificationRequired that enforces the consent page for affected users. -func PublicAvatarConsent(user *models.User, w http.ResponseWriter, r *http.Request) (handled bool) { - // Is the enforcement date live? - if time.Now().Before(config.PublicAvatarEnforcementDate) { - return - } - - // If the current user has a non-public avatar and has not consented. - if user.ProfilePhoto.ID > 0 && user.ProfilePhoto.Visibility != models.PhotoPublic { - if user.GetProfileField("public_avatar_consent") == "true" { - return - } - - templates.Redirect(w, "/settings/public-avatar-consent?next="+url.QueryEscape(r.URL.String())) - return true - } - - return -} diff --git a/pkg/models/shy_accounts.go b/pkg/models/shy_accounts.go index 4d037c9..8777ed1 100644 --- a/pkg/models/shy_accounts.go +++ b/pkg/models/shy_accounts.go @@ -1,6 +1,6 @@ package models -// Supplementary functions to do with Shy Accounts and PublicAvatar consent. +// Supplementary functions to do with Shy Accounts. import "code.nonshy.com/nonshy/website/pkg/log" @@ -96,38 +96,3 @@ func MapShyAccounts(users []*User) ShyMap { func (um ShyMap) Get(id uint64) bool { return um[id] } - -// MapPublicAvatarConsent checks a set of users if they have answered the public avatar consent form. -func MapPublicAvatarConsent(users []*User) (map[uint64]bool, error) { - var ( - userIDs = []uint64{} - result = map[uint64]bool{} - ) - for _, user := range users { - userIDs = append(userIDs, user.ID) - result[user.ID] = false - } - - type record struct { - UserID uint64 - Value string - } - var rows = []record{} - - if res := DB.Table( - "profile_fields", - ).Select( - "user_id, value", - ).Where( - "user_id IN ? AND name='public_avatar_consent'", - userIDs, - ).Scan(&rows); res.Error != nil { - return nil, res.Error - } - - for _, row := range rows { - result[row.UserID] = row.Value == "true" - } - - return result, nil -} diff --git a/pkg/models/user.go b/pkg/models/user.go index 6e12f5c..76022ac 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -637,12 +637,8 @@ func (u *User) NameOrUsername() string { // // Expects that UserRelationships are available on the user. func (u *User) VisibleAvatarURL(currentUser *User) string { - // Can the viewer see the picture based on its visibility setting? canSee, visibility := u.CanSeeProfilePicture(currentUser) - - // Or has the owner consented on the Public Avatar policy? - consent := u.GetProfileField("public_avatar_consent") == "true" - if canSee || consent { + if canSee { return config.PhotoWebPath + "/" + u.ProfilePhoto.CroppedFilename } diff --git a/pkg/models/user_relationship.go b/pkg/models/user_relationship.go index ca67ee9..ebaf141 100644 --- a/pkg/models/user_relationship.go +++ b/pkg/models/user_relationship.go @@ -1,17 +1,14 @@ package models -import "code.nonshy.com/nonshy/website/pkg/log" - // UserRelationship fields - how a target User relates to the CurrentUser, especially // with regards to whether the User's friends-only or private profile picture should show. // The zero-values should fail safely: in case the UserRelationship isn't populated correctly, // private profile pics show as private by default. type UserRelationship struct { - Computed bool // check whether the SetUserRelationships function has been run - IsFriend bool // if true, a friends-only profile pic can show - IsPrivateGranted bool // if true, a private profile pic can show - IsInnerCirclePeer bool // if true, the current user is in the inner circle so may see circle-only profile picture - PublicAvatarConsent bool // if true, this user answered the Public Avatar consent form + Computed bool // check whether the SetUserRelationships function has been run + IsFriend bool // if true, a friends-only profile pic can show + IsPrivateGranted bool // if true, a private profile pic can show + IsInnerCirclePeer bool // if true, the current user is in the inner circle so may see circle-only profile picture } // SetUserRelationships updates a set of User objects to populate their UserRelationships in @@ -38,12 +35,6 @@ func SetUserRelationships(currentUser *User, users []*User) error { privateMap[id] = nil } - // Get user PublicAvatar consent maps. - consent, err := MapPublicAvatarConsent(users) - if err != nil { - log.Error("MapPublicAvatarConsent: %s", err) - } - // Inject the UserRelationships. for _, u := range users { u.UserRelationship.IsInnerCirclePeer = isInnerCircle @@ -62,10 +53,6 @@ func SetUserRelationships(currentUser *User, users []*User) error { if _, ok := privateMap[u.ID]; ok { u.UserRelationship.IsPrivateGranted = true } - - if v, ok := consent[u.ID]; ok { - u.UserRelationship.PublicAvatarConsent = v - } } return nil } diff --git a/pkg/router/router.go b/pkg/router/router.go index a2c778d..a5bb6ba 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -48,7 +48,6 @@ func New() http.Handler { mux.Handle("/me", middleware.LoginRequired(account.Dashboard())) mux.Handle("/settings", middleware.LoginRequired(account.Settings())) mux.Handle("/settings/age-gate", middleware.LoginRequired(account.AgeGate())) - mux.Handle("/settings/public-avatar-consent", middleware.LoginRequired(account.PublicAvatarConsent())) mux.Handle("/account/two-factor/setup", middleware.LoginRequired(account.Setup2FA())) mux.Handle("/account/delete", middleware.LoginRequired(account.Delete())) mux.Handle("/account/deactivate", middleware.LoginRequired(account.Deactivate())) diff --git a/pkg/templates/template_vars.go b/pkg/templates/template_vars.go index 339adc2..f73e8f8 100644 --- a/pkg/templates/template_vars.go +++ b/pkg/templates/template_vars.go @@ -23,9 +23,6 @@ func MergeVars(r *http.Request, m map[string]interface{}) { // Integrations m["TurnstileCAPTCHA"] = config.Current.Turnstile - // Temporary? variables for migration efforts on PublicAvatar consent. - m["PublicAvatarEnforcementDate"] = config.PublicAvatarEnforcementDate - if r == nil { return } diff --git a/web/templates/account/public_avatar_consent.html b/web/templates/account/public_avatar_consent.html deleted file mode 100644 index c23d9da..0000000 --- a/web/templates/account/public_avatar_consent.html +++ /dev/null @@ -1,296 +0,0 @@ -{{define "title"}}An update about your Default Profile Picture{{end}} -{{define "content"}} -
-
-
-
-

- An update about your Default Profile Picture -

-

- Please review the upcoming website change about our Default Profile Picture policy -

-
-
-
- -
-
-
-
- -
- -
-

- This page serves as a notification about an upcoming change to the {{PrettyTitle}} site - policy around the visibility of your square cropped Default Profile Picture - (which we will refer to as your "Avatar" for the purpose of this page). -

- -

- Beginning on {{.PublicAvatarEnforcementDate.Format "January 2, 2006"}}, - all {{PrettyTitle}} members will be required to make their Avatar (the square cropped, - default profile picture which includes your face) visible to all members of the website. - After {{.PublicAvatarEnforcementDate.Format "January 2"}}, you will not be permitted to - use the chat room, forums, site gallery or other 'certification required' pages until you - have responded to this consent form by answering the prompt at the bottom of this page. -

- - - -
- -

Summary of the change

- -
    -
  • - On the {{PrettyTitle}} website, all square cropped default profile pictures - will become visible to everybody on the site, instead of showing as a yellow or purple - placeholder image when your full-size profile picture was set to "Friends-only" or "Private" - visibility. -
  • -
  • - The full size profile photo on your gallery can remain as "Friends-only" or - "Private" if you want; but the square Avatar shown next to your name on most pages of the - website will be visible to all logged-in members. -
  • -
  • - The website policy that your Avatar must show your face will also be more - strictly enforced along with this change. We want to know that everybody on {{PrettyTitle}} - has a face that we can all see. -
  • -
  • - Your consent is required for this change. If your - profile picture is currently non-public, we will not begin showing it - to others on the website until you acknowledge and agree to this change in site policy. -
  • -
- -
- -

What is being changed about our Avatars?

- -

- Previously, it was possible to set your Default Profile Picture on your gallery page as - "Private" or "Friends-only" visibility, and it would cause your square cropped Avatar - icon to show as a placeholder image to people who were not allowed to see the full-size copy - on your gallery. -

- -

- For example, if your profile picture was set to "Friends-only" then a - yellow placeholder avatar - would be shown in its place to people who are not on your Friends list, or a - purple placeholder avatar - would stand in for your "Private" profile picture to people who you did not grant access. -

- -

- Going forward, the square cropped Avatar images will be moved to become - visible to everybody who is logged-in to the website. Here - is an example of how your profile card may look to people before, and after - this change: -

-
- -
-
- - Before: - - -
-
-
- {{if eq .CurrentUser.ProfilePhoto.Visibility "friends"}} - - {{else if eq .CurrentUser.ProfilePhoto.Visibility "private"}} - - {{else if .CurrentUser.ProfilePhoto.ID}} - - {{else}} - - {{end}} -
-
-
-

- {{.CurrentUser.NameOrUsername}} -

-

- - {{.CurrentUser.Username}} -

-
-
-
- -
- - After: - - -
-
-
- {{if .CurrentUser.ProfilePhoto.ID}} - - {{else}} - - {{end}} -
-
-
-

- {{.CurrentUser.NameOrUsername}} -

-

- - {{.CurrentUser.Username}} -

-
-
-
-
- - - {{if and (.CurrentUser.ProfilePhoto.ID) (eq .CurrentUser.ProfilePhoto.Visibility "public")}} -
- Notice: your default profile picture is already set to 'Public' visibility, - so this change in site policy will not affect you. -
- {{end}} - -
-
- -

Your full-size profile picture can still remain private

- -

- This change in website policy only applies to the - square cropped Avatar image of your profile picture -- the - image shown on the top of your profile page and next to your name on the chat - room, forums, and other places around the {{PrettyTitle}} website. -

- -

- Your full size default profile photo can still be kept on "Friends-only" - or "Private" visibility. So, for example: if your default profile photo is a full-body nude - picture that includes your face, you could crop your Avatar to show only your face (visible - to everybody) but you can leave the full-size photo on Private if you don't want everybody - to see it. -

- -
- - - -

- If your profile picture is currently "Private" or "Friends-only," we will not - automatically reveal your Avatar to everybody without your consent. We know that for some of - you, the ability to hide your face picture from other members on the site is very important. -

- -

- While the new policy will go into effect on {{.PublicAvatarEnforcementDate.Format "January 2, 2006"}}, - you may accept the updated policy early by clicking on the checkbox below. - After {{.PublicAvatarEnforcementDate.Format "January 2"}}, if you have not yet - accepted the new policy, you will be shown this page any time you access the "Certification Required" - areas of the website (such as the chat room, forums, gallery and member directory). All members who - have a non-public profile picture will need to accept this change after that date to continue using - the website. -

-
- -
- - {{InputCSRF}} - -
- - -

- After accepting this change: if your default profile picture is currently non-public, the - square cropped avatar image will become visible for everybody. -

-
- -
- -
- -
- -
-
- -

What if I disagree with this change?

- -

- After {{.PublicAvatarEnforcementDate.Format "January 2, 2006"}}, when this change - in website policy goes live, members who have a non-public default profile picture and have - not consented to the above update will no longer have access to the "Certification - Required" areas of the website. -

- -

- That is: the Chat Room, Forums, Site Gallery, and Member Directory will no longer be accessible to - you from that time. When visiting any of those areas of the website, you will be redirected to - this consent page which you will need to agree to before you can continue using the website. -

- -

- You will still have access to your Friends list, Messages, profile pages and your account settings - so that you can make arrangements with your friends to connect on a different platform. - If this change in site policy is simply incompatible with you, then we would ask that you - delete your {{PrettyTitle}} account. -

-
-
-
-
-
-
- -
- - -{{end}} diff --git a/web/templates/account/settings.html b/web/templates/account/settings.html index a7c3cb6..ba7d67c 100644 --- a/web/templates/account/settings.html +++ b/web/templates/account/settings.html @@ -113,15 +113,6 @@ -
  • - - Public Avatar Consent -

    - Review and acknowledge the change in default profile picture policy. -

    -
    -
  • -
  • Private Photos diff --git a/web/templates/partials/user_avatar.html b/web/templates/partials/user_avatar.html index 9c40120..2d96b3d 100644 --- a/web/templates/partials/user_avatar.html +++ b/web/templates/partials/user_avatar.html @@ -5,11 +5,11 @@
    {{if .ProfilePhoto.ID}} - {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}} + {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}} - {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}} - {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}} {{else}} @@ -26,11 +26,11 @@
    {{if .ProfilePhoto.ID}} - {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}} + {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}} - {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}} - {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}} {{else}} @@ -47,11 +47,11 @@
    {{if .ProfilePhoto.ID}} - {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}} + {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}} - {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}} - {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}} {{else}} @@ -68,11 +68,11 @@
    {{if .ProfilePhoto.ID}} - {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}} + {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}} - {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}} - {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}} {{else}} @@ -89,11 +89,11 @@
    {{if .ProfilePhoto.ID}} - {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}} + {{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}} - {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}} - {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}} + {{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}} {{else}}