dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit 2deda54d412f8d2b9e170901542cceda7781725b
parent ea5318ae9b2a8642a4786496fa5a9f6b46314942
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Sat, 10 Jun 2023 22:49:34 -0700

option to confirm before opening external links

Diffstat:
Acmd/dkf/migrations/140.sql | 4++++
Mpkg/database/tableChatMessages.go | 21++++++++++++++++++---
Mpkg/database/tableUsers.go | 1+
Mpkg/web/handlers/api/v1/messages.qtpl | 2+-
Mpkg/web/handlers/api/v1/messages.qtpl.go | 2+-
Mpkg/web/handlers/data.go | 5+++++
Mpkg/web/handlers/handlers.go | 10++++++++++
Apkg/web/public/views/pages/external-link1.gohtml | 9+++++++++
Mpkg/web/public/views/pages/settings/chat.gohtml | 7+++++++
Mpkg/web/web.go | 1+
10 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/cmd/dkf/migrations/140.sql b/cmd/dkf/migrations/140.sql @@ -0,0 +1,4 @@ +-- +migrate Up +ALTER TABLE users ADD COLUMN confirm_external_links TINYINT(1) NOT NULL DEFAULT 0; + +-- +migrate Down diff --git a/pkg/database/tableChatMessages.go b/pkg/database/tableChatMessages.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "math" + "net/url" "regexp" "strings" "time" @@ -255,11 +256,25 @@ func (m *ChatMessage) TrimMe() string { return "<p>" + strings.TrimPrefix(m.Message, "<p>/me ") } -func (m *ChatMessage) MsgToDisplay() string { +var externalLinkRgx = regexp.MustCompile(`<a href="([^"]+)" rel="noopener noreferrer" target="_blank">`) + +func (m *ChatMessage) MsgToDisplay(authUser *User) string { + var msg string if m.IsMe() { - return m.TrimMe() + msg = m.TrimMe() + } else { + msg = m.Message } - return m.Message + if authUser.ConfirmExternalLinks { + msg = externalLinkRgx.ReplaceAllStringFunc(msg, func(s string) string { + original := externalLinkRgx.FindStringSubmatch(s)[1] + if strings.HasPrefix(original, "/external-link/") { + return s + } + return `<a href="/external-link/` + url.PathEscape(original) + `" rel="noopener noreferrer" target="_blank">` + }) + } + return msg } func (m *ChatMessage) Delete(db *DkfDB) error { diff --git a/pkg/database/tableUsers.go b/pkg/database/tableUsers.go @@ -118,6 +118,7 @@ type User struct { AFK bool UseStream bool SyntaxHighlightCode string + ConfirmExternalLinks bool HighlightOwnMessages bool `gorm:"-"` } diff --git a/pkg/web/handlers/api/v1/messages.qtpl b/pkg/web/handlers/api/v1/messages.qtpl @@ -419,7 +419,7 @@ {%- endif -%} {%- endif -%} {%- endif -%} - <span {%= unesc(e.User.GenerateChatStyle()) %}><span class="o-wrap">{%s= unesc(e.MsgToDisplay()) %}</span></span> + <span {%= unesc(e.User.GenerateChatStyle()) %}><span class="o-wrap">{%s= unesc(e.MsgToDisplay(AuthUser)) %}</span></span> {%- endif -%} </div> {%- endif -%} diff --git a/pkg/web/handlers/api/v1/messages.qtpl.go b/pkg/web/handlers/api/v1/messages.qtpl.go @@ -1109,7 +1109,7 @@ func StreamRenderMessage(qw422016 *qt422016.Writer, idx int, e database.ChatMess //line messages.qtpl:422 qw422016.N().S(`><span class="o-wrap">`) //line messages.qtpl:422 - qw422016.N().S(unesc(e.MsgToDisplay())) + qw422016.N().S(unesc(e.MsgToDisplay(AuthUser))) //line messages.qtpl:422 qw422016.N().S(`</span></span> `) diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go @@ -672,6 +672,7 @@ type settingsChatData struct { DisplayKickButton bool DisplayHellbanButton bool UseStream bool + ConfirmExternalLinks bool NotifyChessGames bool NotifyChessMove bool NotifyNewMessage bool @@ -926,3 +927,7 @@ type chessData struct { type powHelperData struct { Difficulty int64 } + +type externalLink1Data struct { + Link string +} diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -2448,6 +2448,13 @@ func RoomChatSettingsHandler(c echo.Context) error { return c.Render(http.StatusOK, "chat-room-settings", data) } +func ExternalLink1Handler(c echo.Context) error { + original, _ := url.PathUnescape(c.Param("original")) + var data externalLink1Data + data.Link = original + return c.Render(http.StatusOK, "external-link1", data) +} + func ExternalLinkHandler(c echo.Context) error { service := c.Param("service") original, _ := url.PathUnescape(c.Param("original")) @@ -2565,6 +2572,7 @@ func SettingsChatHandler(c echo.Context) error { data.NotifyChessGames = authUser.NotifyChessGames data.NotifyChessMove = authUser.NotifyChessMove data.UseStream = authUser.UseStream + data.ConfirmExternalLinks = authUser.ConfirmExternalLinks if c.Request().Method == http.MethodGet { return c.Render(http.StatusOK, "settings.chat", data) @@ -3211,6 +3219,7 @@ func changeSettingsForm(c echo.Context, data settingsChatData) error { data.NotifyChessGames = utils.DoParseBool(c.Request().PostFormValue("notify_chess_games")) data.NotifyChessMove = utils.DoParseBool(c.Request().PostFormValue("notify_chess_move")) data.UseStream = utils.DoParseBool(c.Request().PostFormValue("use_stream")) + data.ConfirmExternalLinks = utils.DoParseBool(c.Request().PostFormValue("confirm_external_links")) data.HellbanOpacity = utils.DoParseF64(c.Request().PostFormValue("hellban_opacity")) data.CodeBlockHeight = utils.DoParseInt64(c.Request().PostFormValue("code_block_height")) //data.NotifyNewMessageSound = utils.DoParseInt64(c.Request().PostFormValue("notify_new_message_sound")) @@ -3254,6 +3263,7 @@ func changeSettingsForm(c echo.Context, data settingsChatData) error { authUser.NotifyChessGames = data.NotifyChessGames authUser.NotifyChessMove = data.NotifyChessMove authUser.UseStream = data.UseStream + authUser.ConfirmExternalLinks = data.ConfirmExternalLinks authUser.Theme = data.Theme //authUser.NotifyNewMessageSound = data.NotifyNewMessageSound //authUser.NotifyTaggedSound = data.NotifyTaggedSound diff --git a/pkg/web/public/views/pages/external-link1.gohtml b/pkg/web/public/views/pages/external-link1.gohtml @@ -0,0 +1,8 @@ +{{ define "content" }} +<div class="container"> + Navigate to external link: + <div> + <a href="{{ .Data.Link }}">{{ .Data.Link }}</a> + </div> +</div> +{{ end }} +\ No newline at end of file diff --git a/pkg/web/public/views/pages/settings/chat.gohtml b/pkg/web/public/views/pages/settings/chat.gohtml @@ -194,6 +194,13 @@ </div> <label class="form-check-label" for="use_stream">{{ t "Use chat stream version" . }}</label> </div> + <div class="form-check form-check-1"> + <div class="checkbox-wrapper form-check-input"> + <input class="my-cbx" type="checkbox" name="confirm_external_links" id="confirm_external_links" value="1"{{ if .AuthUser.ConfirmExternalLinks }} checked{{ end }} /> + <label for="confirm_external_links" class="toggle"><span></span></label> + </div> + <label class="form-check-label" for="confirm_external_links">Confirm before opening external links</label> + </div> {{ if $.AuthUser.IsModerator }} <div class="form-check form-check-1"> <div class="checkbox-wrapper form-check-input"> diff --git a/pkg/web/web.go b/pkg/web/web.go @@ -229,6 +229,7 @@ func getMainServer(db *database.DkfDB, i18nBundle *i18n.Bundle, renderer *tmp.Te authGroup.POST("/chat/:roomName/delete", handlers.ChatDeleteHandler) authGroup.GET("/chat/:roomName/settings", handlers.RoomChatSettingsHandler) authGroup.POST("/chat/:roomName/settings", handlers.RoomChatSettingsHandler) + authGroup.GET("/external-link/:original", handlers.ExternalLink1Handler) authGroup.GET("/external-link/:service/:original", handlers.ExternalLinkHandler) moderatorGroup := e.Group("", middlewares.IsModeratorMiddleware) moderatorGroup.POST("/api/v1/users/:userID/hellban", v1.UserHellbanHandler)