Warning before user deletes their entire gallery

* If a user is about to delete all remaining gallery photos, and their
  account is certified, show a warning banner and extra confirmation
  modal before they continue with the deletion, that their account will
  lose its certified status.
* Minor improvements to change logs around cert photos.
This commit is contained in:
Noah Petherbridge 2024-12-31 15:56:08 -08:00
parent 7415a2ece1
commit ea1c4aab18
4 changed files with 55 additions and 4 deletions

View File

@ -58,7 +58,8 @@ func BatchEdit() http.HandlerFunc {
// Validate permission to edit all of these photos.
var (
ownerIDs []uint64
ownerIDs []uint64
allMyPhotos = true // all photos belong to the current user
)
for _, photo := range photos {
@ -68,6 +69,10 @@ func BatchEdit() http.HandlerFunc {
}
ownerIDs = append(ownerIDs, photo.UserID)
if photo.UserID != currentUser.ID {
allMyPhotos = false
}
}
// Load the photo owners.
@ -92,6 +97,15 @@ func BatchEdit() http.HandlerFunc {
}
}
// Warning in case the user will delete ALL of their photos and lose their certified status.
var warningDeletingAllPhotos bool
if intent == "delete" && allMyPhotos && currentUser.Certified {
photoCount := models.CountPhotos(currentUser.ID)
if int64(len(photos)) >= photoCount {
warningDeletingAllPhotos = true
}
}
// Confirm batch deletion or edit.
if r.Method == http.MethodPost {
@ -130,6 +144,9 @@ func BatchEdit() http.HandlerFunc {
var vars = map[string]interface{}{
"Intent": intent,
"Photos": photos,
// Warn if the current user will delete all their photos.
"WarningDeletingAllPhotos": warningDeletingAllPhotos,
}
if err := tmpl.Execute(w, r, vars); err != nil {

View File

@ -193,7 +193,13 @@ func Certification() http.HandlerFunc {
// Log the change. Note the original IP and GeoIP insights - we once saw a spammer upload
// their cert photo from Nigeria, and before we could reject it, they removed and reuploaded
// it from New York using a VPN. If it wasn't seen in real time, this might have slipped by.
var insights string
var (
logMessage = "Uploaded a new certification photo."
insights string
)
if isSecondary {
logMessage = "Uploaded a secondary photo ID for certification."
}
if i, err := geoip.GetRequestInsights(r); err == nil {
insights = i.String()
} else {
@ -204,7 +210,8 @@ func Certification() http.HandlerFunc {
"certification_photos",
currentUser.ID,
fmt.Sprintf(
"Uploaded a new certification photo.\n\n* From IP address: %s\n* GeoIP insight: %s",
"%s\n\n* From IP address: %s\n* GeoIP insight: %s",
logMessage,
cert.IPAddress,
insights,
),

View File

@ -155,6 +155,9 @@ func MaybeRevokeCertificationForEmptyGallery(user *User) bool {
log.Error("Couldn't save feedback from user auto-revoking their cert photo: %s", err)
}
// Update the cert photo's change log.
LogEvent(user, nil, ChangeLogRejected, "certification_photos", user.ID, "Their cert photo was automatically rejected because they deleted their entire photo gallery.")
return true
}

View File

@ -150,9 +150,33 @@
this photo?
{{- end}}
</div>
<!-- Deleting last photos warning about certification loss -->
{{if .WarningDeletingAllPhotos}}
<div class="block">
<div class="notification is-danger is-light content">
<p>
<i class="fa fa-exclamation-triangle mr-1"></i>
<strong>Certification Photo Warning</strong>
</p>
<p>
You are about to delete ALL remaining photos on your gallery. If you continue with
this action, <strong>your Certification Photo will be automatically revoked</strong>
and your account will lose its Certified status. You would then need to submit a new
Certification Photo for approval (after uploading pictures back onto your gallery) to
continue using {{PrettyTitle}}.
</p>
</div>
</div>
{{end}}
<div class="block has-text-center">
{{if eq .Intent "delete"}}
<button type="submit" class="button is-danger">Delete Photo{{Pluralize (len .Photos)}}</button>
<button type="submit" class="button is-danger nonshy-confirm-submit"
{{if .WarningDeletingAllPhotos}}data-confirm="You are about to delete your final {{len .Photos}} photo{{Pluralize (len .Photos)}} from your gallery, which will cause your Certification Photo to be automatically revoked.\n\nConfirm that you want to delete your final pictures. By continuing, your account will lose its Certified status and, if you wish to continue using {{.Title}}, you will need to submit a new Certification Photo for review after uploading some pictures to your gallery again."{{end}}
>
Delete Photo{{Pluralize (len .Photos)}}
</button>
{{else}}
<button type="submit" class="button is-primary">Update Photo{{Pluralize (len .Photos)}}</button>
{{end}}