commit c7827f91203836305bdafaa2ddcd31824ac8b61b
parent db33df66ead1546d00eae3a1528d3fdc53e8be7d
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Sun, 4 Dec 2022 23:56:24 -0500
add restore link button for moderators
Diffstat:
4 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/pkg/database/tableLinks.go b/pkg/database/tableLinks.go
@@ -8,6 +8,7 @@ import (
"github.com/ProtonMail/go-crypto/openpgp/armor"
"github.com/ProtonMail/go-crypto/openpgp/packet"
"github.com/google/uuid"
+ "github.com/sirupsen/logrus"
"html"
"strings"
"time"
@@ -30,6 +31,16 @@ func (l Link) DescriptionSafe() string {
return html.EscapeString(l.Description)
}
+func (l *Link) Save() error {
+ return DB.Save(l).Error
+}
+
+func (l *Link) DoSave() {
+ if err := DB.Debug().Save(l).Error; err != nil {
+ logrus.Error(err)
+ }
+}
+
func CreateLink(url, title, description, shorthand string) (out Link, err error) {
out = Link{UUID: uuid.New().String(), URL: url, Title: title, Description: description}
if shorthand != "" {
diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go
@@ -1066,7 +1066,7 @@ func ForgotPasswordHandler(c echo.Context) error {
// Receive and validate new password
data.Step = 3
- // Step3 is guarded by the "partial-recovery2-token" cookie that must be valid
+ // Step3 is guarded by the "partial-recovery-token" cookie that must be valid
partialRecoveryCookie, err := c.Cookie(hutils.PartialRecoveryCookieName)
if err != nil {
return c.Redirect(http.StatusFound, "/")
@@ -1157,7 +1157,7 @@ where fts5_forum_threads match ? and t.is_club = 0 order by rank limit 100`, dat
}
func LinksHandler(c echo.Context) error {
- //authUser := c.Get("authUser").(*database.User)
+ authUser := c.Get("authUser").(*database.User)
var data linksData
resultsPerPage := int64(100)
@@ -1187,7 +1187,11 @@ ORDER BY l.title COLLATE NOCASE ASC`, filterCategory).Scan(&data.Links)
if searchedURL, err := url.Parse(data.Search); err == nil {
h := searchedURL.Scheme + "://" + searchedURL.Hostname()
var l database.Link
- if err := database.DB.First(&l, "url = ?", h).Error; err == nil {
+ query := database.DB
+ if authUser.IsModerator() {
+ query = query.Unscoped()
+ }
+ if err := query.First(&l, "url = ?", h).Error; err == nil {
data.Links = append(data.Links, l)
}
data.LinksCount = int64(len(data.Links))
@@ -1452,6 +1456,20 @@ func NewLinkHandler(c echo.Context) error {
return c.Render(http.StatusOK, "new-link", data)
}
+func RestoreLinkHandler(c echo.Context) error {
+ authUser := c.Get("authUser").(*database.User)
+ if !authUser.IsModerator() {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ linkUUID := c.Param("linkUUID")
+ var link database.Link
+ if err := database.DB.Unscoped().First(&link, "uuid = ?", linkUUID).Error; err != nil {
+ return c.Redirect(http.StatusFound, c.Request().Referer())
+ }
+ database.DB.Unscoped().Model(&database.Link{}).Where("id", link.ID).Update("deleted_at", nil)
+ return c.Redirect(http.StatusFound, c.Request().Referer())
+}
+
func EditLinkHandler(c echo.Context) error {
authUser := c.Get("authUser").(*database.User)
if !authUser.IsModerator() {
diff --git a/pkg/web/public/views/pages/links.gohtml b/pkg/web/public/views/pages/links.gohtml
@@ -38,6 +38,12 @@
{{ range .Data.Links }}
<tr>
<td>
+ {{ if and $.AuthUser.IsModerator .DeletedAt }}
+ <form action="/links/{{ .UUID }}/restore" method="post" class="d-inline">
+ <input type="hidden" name="csrf" value="{{ $.CSRF }}" />
+ <button type="submit" class="btn btn-danger" role="link" style="padding: 0 3px;" title="restore">↻</button>
+ </form>
+ {{ end }}
<a href="/links/{{ .UUID }}">{{ .Title }}</a> - {{ .Description | trunc 100 }}<br />
<a style="color: gray; font-size: 10px; font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;" href="{{ .URL }}" rel="noopener noreferrer" target="_blank">{{ .URL }}</a>
{{ range $idx, $el := .Mirrors }}
diff --git a/pkg/web/web.go b/pkg/web/web.go
@@ -180,6 +180,7 @@ func getMainServer() echo.HandlerFunc {
authGroup.POST("/links/download", handlers.LinksDownloadHandler, middlewares.AuthRateLimitMiddleware(time.Second, 2))
authGroup.GET("/l/:shorthand", handlers.LinkHandler, middlewares.AuthRateLimitMiddleware(time.Second, 2))
authGroup.GET("/links/:linkUUID", handlers.LinkHandler, middlewares.AuthRateLimitMiddleware(time.Second, 2))
+ authGroup.POST("/links/:linkUUID/restore", handlers.RestoreLinkHandler, middlewares.AuthRateLimitMiddleware(time.Second, 2))
authGroup.GET("/links/:linkUUID/edit", handlers.EditLinkHandler, middlewares.AuthRateLimitMiddleware(time.Second, 2))
authGroup.POST("/links/:linkUUID/edit", handlers.EditLinkHandler, middlewares.AuthRateLimitMiddleware(time.Second, 2))
authGroup.GET("/links/:linkUUID/delete", handlers.LinkDeleteHandler)