mirror of
https://codeberg.org/video-prize-ranch/rimgo.git
synced 2026-01-27 17:11:13 +00:00
move sanitization code out of api package
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"codeberg.org/rimgo/rimgo/utils"
|
"codeberg.org/rimgo/rimgo/utils"
|
||||||
"github.com/microcosm-cc/bluemonday"
|
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -101,17 +100,13 @@ func parseAlbum(data gjson.Result) (Album, error) {
|
|||||||
url := value.Get("url").String()
|
url := value.Get("url").String()
|
||||||
url = strings.ReplaceAll(url, "https://i.imgur.com", "")
|
url = strings.ReplaceAll(url, "https://i.imgur.com", "")
|
||||||
|
|
||||||
description := value.Get("metadata.description").String()
|
|
||||||
description = strings.ReplaceAll(description, "\n", "<br>")
|
|
||||||
description = bluemonday.UGCPolicy().Sanitize(description)
|
|
||||||
|
|
||||||
media = append(media, Media{
|
media = append(media, Media{
|
||||||
Id: value.Get("id").String(),
|
Id: value.Get("id").String(),
|
||||||
Name: value.Get("name").String(),
|
Name: value.Get("name").String(),
|
||||||
MimeType: value.Get("mime_type").String(),
|
MimeType: value.Get("mime_type").String(),
|
||||||
Type: value.Get("type").String(),
|
Type: value.Get("type").String(),
|
||||||
Title: value.Get("metadata.title").String(),
|
Title: value.Get("metadata.title").String(),
|
||||||
Description: description,
|
Description: value.Get("metadata.description").String(),
|
||||||
Url: url,
|
Url: url,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,12 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"codeberg.org/rimgo/rimgo/utils"
|
"codeberg.org/rimgo/rimgo/utils"
|
||||||
"github.com/microcosm-cc/bluemonday"
|
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"gitlab.com/golang-commonmark/linkify"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Comment struct {
|
type Comment struct {
|
||||||
@@ -64,50 +60,11 @@ func (client *Client) FetchComments(galleryID string) ([]Comment, error) {
|
|||||||
return parsed.Data, nil
|
return parsed.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var imgurRe = regexp.MustCompile(`https?://imgur\.com/(gallery|a)?/(.*)`)
|
|
||||||
var imgurRe2 = regexp.MustCompile(`https?://imgur\.com/(.*)`)
|
|
||||||
var imgRe = regexp.MustCompile(`https?://i\.imgur\.com/(.*)\.(png|gif|jpe?g|webp)`)
|
|
||||||
var vidRe = regexp.MustCompile(`https?://i\.imgur\.com/(.*)\.(mp4|webm)`)
|
|
||||||
var vidFormatRe = regexp.MustCompile(`\.(mp4|webm)`)
|
|
||||||
var iImgurRe = regexp.MustCompile(`https?://i\.imgur\.com`)
|
|
||||||
|
|
||||||
func parseComment(data json.RawMessage, out *Comment) {
|
func parseComment(data json.RawMessage, out *Comment) {
|
||||||
err := json.Unmarshal(data, &out)
|
err := json.Unmarshal(data, &out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
comment := &out.Comment
|
|
||||||
*comment = strings.ReplaceAll(*comment, "\n", "<br>")
|
|
||||||
|
|
||||||
for _, match := range imgRe.FindAllString(*comment, -1) {
|
|
||||||
img := iImgurRe.ReplaceAllString(match, "")
|
|
||||||
img = `<img src="` + img + `" class="comment__media" loading="lazy"/>`
|
|
||||||
*comment = strings.Replace(*comment, match, img, 1)
|
|
||||||
}
|
|
||||||
for _, match := range vidRe.FindAllString(*comment, -1) {
|
|
||||||
vid := iImgurRe.ReplaceAllString(match, "")
|
|
||||||
vid = `<video class="comment__media" controls loop preload="none" poster="` + vidFormatRe.ReplaceAllString(vid, ".webp") + `"><source type="` + strings.Split(vid, ".")[1] + `" src="` + vid + `" /></video>`
|
|
||||||
*comment = strings.Replace(*comment, match, vid, 1)
|
|
||||||
}
|
|
||||||
for _, l := range linkify.Links(*comment) {
|
|
||||||
origLink := (*comment)[l.Start:l.End]
|
|
||||||
link := `<a href="` + origLink + `">` + origLink + `</a>`
|
|
||||||
*comment = strings.Replace(*comment, origLink, link, 1)
|
|
||||||
}
|
|
||||||
*comment = imgurRe.ReplaceAllString(*comment, "/$1/$2")
|
|
||||||
*comment = imgurRe2.ReplaceAllString(*comment, "/$1")
|
|
||||||
|
|
||||||
p := bluemonday.UGCPolicy()
|
|
||||||
p.AllowImages()
|
|
||||||
p.AllowElements("video", "source")
|
|
||||||
p.AllowAttrs("src", "tvpe").OnElements("source")
|
|
||||||
p.AllowAttrs("controls", "loop", "preload", "poster").OnElements("video")
|
|
||||||
p.AllowAttrs("class", "loading").OnElements("img", "video")
|
|
||||||
p.RequireNoReferrerOnLinks(true)
|
|
||||||
p.RequireNoFollowOnLinks(true)
|
|
||||||
p.RequireCrossOriginAnonymous(true)
|
|
||||||
*comment = p.Sanitize(*comment)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type commentArray []Comment
|
type commentArray []Comment
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ import (
|
|||||||
|
|
||||||
func (r *renderer) registerHelpers() {
|
func (r *renderer) registerHelpers() {
|
||||||
funcmap := map[string]any{
|
funcmap := map[string]any{
|
||||||
"noteq": noteq,
|
"noteq": noteq,
|
||||||
"ifNonZeroTime": ifNonZeroTime,
|
"ifNonZeroTime": ifNonZeroTime,
|
||||||
"relTime": relTime,
|
"relTime": relTime,
|
||||||
"rewriteUrl": rewriteUrl,
|
"rewriteUrl": rewriteUrl,
|
||||||
|
"sanitizeDescription": sanitizeDescription,
|
||||||
|
"sanitizeComment": sanitizeComment,
|
||||||
}
|
}
|
||||||
raymond.RegisterHelpers(funcmap)
|
raymond.RegisterHelpers(funcmap)
|
||||||
}
|
}
|
||||||
|
|||||||
53
render/sanitize.go
Normal file
53
render/sanitize.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/microcosm-cc/bluemonday"
|
||||||
|
"gitlab.com/golang-commonmark/linkify"
|
||||||
|
)
|
||||||
|
|
||||||
|
var imgurRe = regexp.MustCompile(`https?://imgur\.com/(gallery|a)?/(.*)`)
|
||||||
|
var imgurRe2 = regexp.MustCompile(`https?://imgur\.com/(.*)`)
|
||||||
|
var imgRe = regexp.MustCompile(`https?://i\.imgur\.com/(.*)\.(png|gif|jpe?g|webp)`)
|
||||||
|
var vidRe = regexp.MustCompile(`https?://i\.imgur\.com/(.*)\.(mp4|webm)`)
|
||||||
|
var vidFormatRe = regexp.MustCompile(`\.(mp4|webm)`)
|
||||||
|
var iImgurRe = regexp.MustCompile(`https?://i\.imgur\.com`)
|
||||||
|
|
||||||
|
func sanitizeDescription(src string) string {
|
||||||
|
src = strings.ReplaceAll(src, "\n", "<br>")
|
||||||
|
return bluemonday.UGCPolicy().Sanitize(src)
|
||||||
|
}
|
||||||
|
func sanitizeComment(src string) string {
|
||||||
|
src = strings.ReplaceAll(src, "\n", "<br>")
|
||||||
|
|
||||||
|
for _, match := range imgRe.FindAllString(src, -1) {
|
||||||
|
img := iImgurRe.ReplaceAllString(match, "")
|
||||||
|
img = `<img src="` + img + `" class="comment__media" loading="lazy"/>`
|
||||||
|
src = strings.Replace(src, match, img, 1)
|
||||||
|
}
|
||||||
|
for _, match := range vidRe.FindAllString(src, -1) {
|
||||||
|
vid := iImgurRe.ReplaceAllString(match, "")
|
||||||
|
vid = `<video class="comment__media" controls loop preload="none" poster="` + vidFormatRe.ReplaceAllString(vid, ".webp") + `"><source type="` + strings.Split(vid, ".")[1] + `" src="` + vid + `" /></video>`
|
||||||
|
src = strings.Replace(src, match, vid, 1)
|
||||||
|
}
|
||||||
|
for _, l := range linkify.Links(src) {
|
||||||
|
origLink := (src)[l.Start:l.End]
|
||||||
|
link := `<a href="` + origLink + `">` + origLink + `</a>`
|
||||||
|
src = strings.Replace(src, origLink, link, 1)
|
||||||
|
}
|
||||||
|
src = imgurRe.ReplaceAllString(src, "/$1/$2")
|
||||||
|
src = imgurRe2.ReplaceAllString(src, "/$1")
|
||||||
|
|
||||||
|
p := bluemonday.UGCPolicy()
|
||||||
|
p.AllowImages()
|
||||||
|
p.AllowElements("video", "source")
|
||||||
|
p.AllowAttrs("src", "tvpe").OnElements("source")
|
||||||
|
p.AllowAttrs("controls", "loop", "preload", "poster").OnElements("video")
|
||||||
|
p.AllowAttrs("class", "loading").OnElements("img", "video")
|
||||||
|
p.RequireNoReferrerOnLinks(true)
|
||||||
|
p.RequireNoFollowOnLinks(true)
|
||||||
|
p.RequireCrossOriginAnonymous(true)
|
||||||
|
return p.Sanitize(src)
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
{{/equal}}
|
{{/equal}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>{{{this.Comment}}}</p>
|
<p>{{{sanitizeComment(this.Comment)}}}</p>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<span title="{{this.CreatedAt}}">{{relTime(this.CreatedAt)}}</span>
|
<span title="{{this.CreatedAt}}">{{relTime(this.CreatedAt)}}</span>
|
||||||
{{#ifNonZeroTime this.DeletedAt}}
|
{{#ifNonZeroTime this.DeletedAt}}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<img class="object-cover block w-full h-[300px] sm:w-[120px] sm:h-[140px] rounded-lg rounded-b-none sm:rounded-b-lg" src="{{this.Post.Cover.Url}}" alt="">
|
<img class="object-cover block w-full h-[300px] sm:w-[120px] sm:h-[140px] rounded-lg rounded-b-none sm:rounded-b-lg" src="{{this.Post.Cover.Url}}" alt="">
|
||||||
<div class="flex flex-col gap-2 bg-slate-600 p-4 rounded-lg rounded-t-none sm:rounded-t-lg w-full">
|
<div class="flex flex-col gap-2 bg-slate-600 p-4 rounded-lg rounded-t-none sm:rounded-t-lg w-full">
|
||||||
<div class="flex flex-col h-full">
|
<div class="flex flex-col h-full">
|
||||||
<p class="md-container">{{{this.Comment}}}</p>
|
<p class="md-container">{{{sanitizeComment(this.Comment)}}}</p>
|
||||||
<div class="grow"></div>
|
<div class="grow"></div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<span title="{{this.CreatedAt}}">{{relTime(this.CreatedAt)}}</span>
|
<span title="{{this.CreatedAt}}">{{relTime(this.CreatedAt)}}</span>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
{{/equal}}
|
{{/equal}}
|
||||||
|
|
||||||
{{#if this.Description}}
|
{{#if this.Description}}
|
||||||
<p>{{{this.Description}}}</p>
|
<p>{{{sanitizeDescription(this.Description)}}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user