commit 0f28720d39dbc79636a7c7e566990d316af1d2f3
parent 8be8abdf59cf72c8d6c1dbc225dc2ecc5aac0bf9
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Mon, 12 Jun 2023 20:16:01 -0700
move code
Diffstat:
2 files changed, 235 insertions(+), 231 deletions(-)
diff --git a/pkg/web/handlers/chat.go b/pkg/web/handlers/chat.go
@@ -4,11 +4,19 @@ import (
"dkforest/pkg/captcha"
"dkforest/pkg/config"
"dkforest/pkg/database"
+ dutils "dkforest/pkg/database/utils"
+ "dkforest/pkg/hashset"
"dkforest/pkg/managers"
"dkforest/pkg/utils"
hutils "dkforest/pkg/web/handlers/utils"
+ "github.com/PuerkitoBio/goquery"
+ "github.com/asaskevich/govalidator"
+ "github.com/jinzhu/gorm"
"github.com/labstack/echo"
+ "github.com/sirupsen/logrus"
"net/http"
+ "strconv"
+ "strings"
"time"
)
@@ -190,3 +198,230 @@ func handleChatPasswordPost(db *database.DkfDB, c echo.Context, data chatData, a
hutils.CreateRoomCookie(c, int64(data.Room.ID), hashedPassword, key)
return c.Redirect(http.StatusFound, "/chat/"+data.Room.Name)
}
+
+func ChatArchiveHandler(c echo.Context) error {
+ authUser := c.Get("authUser").(*database.User)
+ db := c.Get("database").(*database.DkfDB)
+ var data chatArchiveData
+ data.DateFormat = authUser.GetDateFormat()
+ roomName := c.Param("roomName")
+
+ room, roomKey, err := dutils.GetRoomAndKey(db, c, roomName)
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/chat")
+ }
+
+ data.UUID = c.QueryParam("uuid")
+ data.Room = room
+
+ if data.UUID != "" {
+ msg, err := db.GetRoomChatMessageByUUID(room.ID, data.UUID)
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ nbMsg := 150
+ args := []any{room.ID, authUser.ID, authUser.ID}
+ whereClause := `room_id = ? AND group_id IS NULL AND (to_user_id is null OR to_user_id = ? OR user_id = ?)`
+ if !authUser.DisplayIgnored {
+ args = append(args, authUser.ID)
+ whereClause += ` AND user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)`
+ }
+ raw := `
+ SELECT * FROM (
+ SELECT *
+ FROM chat_messages
+ WHERE ` + whereClause + `
+ AND id >= ?
+ ORDER BY id ASC
+ LIMIT ?
+ )
+ UNION
+ SELECT * FROM (
+ SELECT *
+ FROM chat_messages
+ WHERE ` + whereClause + `
+ AND id < ?
+ ORDER BY id DESC
+ LIMIT ?
+ ) ORDER BY id DESC`
+ args = append(args, msg.ID, nbMsg)
+ args = append(args, args...)
+ db.DB().Raw(raw, args...).Scan(&data.Messages)
+
+ // Manually do Preload("Room")
+ for _, m := range data.Messages {
+ m.Room = data.Room
+ }
+
+ //--- < Manually do a Preload("User") Preload("ToUser") > ---
+ usersIDs := hashset.New[database.UserID]()
+ for _, m := range data.Messages {
+ usersIDs.Insert(m.UserID)
+ if m.ToUserID != nil {
+ usersIDs.Insert(*m.ToUserID)
+ }
+ }
+ users, _ := db.GetUsersByID(usersIDs.ToArray())
+ usersMap := make(map[database.UserID]database.User)
+ for _, u := range users {
+ usersMap[u.ID] = u
+ }
+ for i, m := range data.Messages {
+ if u, ok := usersMap[m.UserID]; ok {
+ data.Messages[i].User = u
+ }
+ if m.ToUserID != nil {
+ if u, ok := usersMap[*m.ToUserID]; ok {
+ data.Messages[i].ToUser = &u
+ }
+ }
+ }
+ //--- </ Manually do a Preload("User") Preload("ToUser") > ---
+
+ } else {
+ if err := db.DB().Table("chat_messages").
+ Where("room_id = ? AND group_id IS NULL AND (to_user_id is null OR to_user_id = ? OR user_id = ?)", room.ID, authUser.ID, authUser.ID).
+ Scopes(func(query *gorm.DB) *gorm.DB {
+ if !authUser.DisplayIgnored {
+ query = query.Where(`user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)`, authUser.ID)
+ }
+ data.CurrentPage, data.MaxPage, data.MessagesCount, query = NewPaginator().SetResultPerPage(300).Paginate(c, query)
+ return query
+ }).
+ Order("id DESC").
+ Preload("Room").
+ Preload("User").
+ Preload("ToUser").
+ Find(&data.Messages).Error; err != nil {
+ logrus.Error(err)
+ }
+ }
+
+ if roomKey != "" {
+ if err := data.Messages.DecryptAll(roomKey); err != nil {
+ return c.NoContent(http.StatusInternalServerError)
+ }
+ }
+
+ return c.Render(http.StatusOK, "chat-archive", data)
+}
+
+func ChatDeleteHandler(c echo.Context) error {
+ authUser := c.Get("authUser").(*database.User)
+ db := c.Get("database").(*database.DkfDB)
+ var data chatDeleteData
+ roomName := c.Param("roomName")
+ room, err := db.GetChatRoomByName(roomName)
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ if !room.IsRoomOwner(*authUser) {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ data.Room = room
+
+ if c.Request().Method == http.MethodPost {
+ if room.IsProtected() {
+ hutils.DeleteRoomCookie(c, int64(room.ID))
+ }
+ db.DeleteChatRoomByID(room.ID)
+ return c.Redirect(http.StatusFound, "/chat")
+ }
+
+ return c.Render(http.StatusOK, "chat-delete", data)
+}
+
+func RoomChatSettingsHandler(c echo.Context) error {
+ authUser := c.Get("authUser").(*database.User)
+ db := c.Get("database").(*database.DkfDB)
+ var data roomChatSettingsData
+ roomName := c.Param("roomName")
+ room, err := db.GetChatRoomByName(roomName)
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ if !room.IsRoomOwner(*authUser) {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ data.Room = room
+
+ if c.Request().Method == http.MethodPost {
+ return c.Redirect(http.StatusFound, "/chat")
+ }
+
+ return c.Render(http.StatusOK, "chat-room-settings", data)
+}
+
+func ChatCreateRoomHandler(c echo.Context) error {
+ authUser := c.Get("authUser").(*database.User)
+ db := c.Get("database").(*database.DkfDB)
+ var data chatCreateRoomData
+ data.CaptchaID, data.CaptchaImg = captcha.New()
+ data.IsEphemeral = true
+ if c.Request().Method == http.MethodPost {
+ data.RoomName = c.Request().PostFormValue("room_name")
+ data.Password = c.Request().PostFormValue("password")
+ data.IsListed = utils.DoParseBool(c.Request().PostFormValue("is_listed"))
+ data.IsEphemeral = utils.DoParseBool(c.Request().PostFormValue("is_ephemeral"))
+ if !govalidator.Matches(data.RoomName, "^[a-zA-Z0-9_]{3,50}$") {
+ data.ErrorRoomName = "invalid room name"
+ return c.Render(http.StatusOK, "chat-create-room", data)
+ }
+ captchaID := c.Request().PostFormValue("captcha_id")
+ captchaInput := c.Request().PostFormValue("captcha")
+ if err := hutils.CaptchaVerifyString(c, captchaID, captchaInput); err != nil {
+ data.ErrCaptcha = err.Error()
+ return c.Render(http.StatusOK, "chat-create-room", data)
+ }
+ passwordHash := ""
+ if data.Password != "" {
+ passwordHash = database.GetRoomPasswordHash(data.Password)
+ }
+ if _, err := db.CreateRoom(data.RoomName, passwordHash, authUser.ID, data.IsListed); err != nil {
+ data.Error = err.Error()
+ return c.Render(http.StatusOK, "chat-create-room", data)
+ }
+ return c.Redirect(http.StatusFound, "/chat/"+data.RoomName)
+ }
+ return c.Render(http.StatusOK, "chat-create-room", data)
+}
+
+func ChatCodeHandler(c echo.Context) error {
+ messageUUID := c.Param("messageUUID")
+ idx, err := strconv.Atoi(c.Param("idx"))
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+
+ authUser := c.Get("authUser").(*database.User)
+ db := c.Get("database").(*database.DkfDB)
+ msg, err := db.GetChatMessageByUUID(messageUUID)
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+
+ if !verifyMsgAuth(db, authUser, &msg) {
+ return c.Redirect(http.StatusFound, "/")
+ }
+
+ doc, err := goquery.NewDocumentFromReader(strings.NewReader(msg.Message))
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ n := doc.Find("pre").Eq(idx)
+ if n == nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+
+ var data chatCodepData
+ data.Code, err = n.Html()
+ if err != nil {
+ return c.Redirect(http.StatusFound, "/")
+ }
+ return c.Render(http.StatusOK, "chat-code", data)
+}
+
+func ChatHelpHandler(c echo.Context) error {
+ var data chatHelpData
+ return c.Render(http.StatusOK, "chat-help", data)
+}
diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go
@@ -4,7 +4,6 @@ import (
"bytes"
"context"
dutils "dkforest/pkg/database/utils"
- "dkforest/pkg/hashset"
"dkforest/pkg/odometer"
"dkforest/pkg/pubsub"
v1 "dkforest/pkg/web/handlers/api/v1"
@@ -13,8 +12,6 @@ import (
"encoding/json"
"errors"
"fmt"
- "github.com/PuerkitoBio/goquery"
- "github.com/jinzhu/gorm"
_ "golang.org/x/image/bmp"
_ "golang.org/x/image/webp"
"image"
@@ -28,7 +25,6 @@ import (
"os/signal"
"path/filepath"
"regexp"
- "strconv"
"strings"
"syscall"
"time"
@@ -1309,32 +1305,6 @@ func getWaitPageDuration() int64 {
return secs
}
-func ChatHelpHandler(c echo.Context) error {
- var data chatHelpData
- return c.Render(http.StatusOK, "chat-help", data)
-}
-
-func RoomChatSettingsHandler(c echo.Context) error {
- authUser := c.Get("authUser").(*database.User)
- db := c.Get("database").(*database.DkfDB)
- var data roomChatSettingsData
- roomName := c.Param("roomName")
- room, err := db.GetChatRoomByName(roomName)
- if err != nil {
- return c.Redirect(http.StatusFound, "/")
- }
- if !room.IsRoomOwner(*authUser) {
- return c.Redirect(http.StatusFound, "/")
- }
- data.Room = room
-
- if c.Request().Method == http.MethodPost {
- return c.Redirect(http.StatusFound, "/chat")
- }
-
- return c.Render(http.StatusOK, "chat-room-settings", data)
-}
-
func ExternalLink1Handler(c echo.Context) error {
original, _ := url.PathUnescape(c.Param("original"))
var data externalLink1Data
@@ -1362,40 +1332,6 @@ func ExternalLinkHandler(c echo.Context) error {
return c.Redirect(http.StatusFound, baseURL+"/"+original)
}
-func ChatCreateRoomHandler(c echo.Context) error {
- authUser := c.Get("authUser").(*database.User)
- db := c.Get("database").(*database.DkfDB)
- var data chatCreateRoomData
- data.CaptchaID, data.CaptchaImg = captcha.New()
- data.IsEphemeral = true
- if c.Request().Method == http.MethodPost {
- data.RoomName = c.Request().PostFormValue("room_name")
- data.Password = c.Request().PostFormValue("password")
- data.IsListed = utils.DoParseBool(c.Request().PostFormValue("is_listed"))
- data.IsEphemeral = utils.DoParseBool(c.Request().PostFormValue("is_ephemeral"))
- if !govalidator.Matches(data.RoomName, "^[a-zA-Z0-9_]{3,50}$") {
- data.ErrorRoomName = "invalid room name"
- return c.Render(http.StatusOK, "chat-create-room", data)
- }
- captchaID := c.Request().PostFormValue("captcha_id")
- captchaInput := c.Request().PostFormValue("captcha")
- if err := hutils.CaptchaVerifyString(c, captchaID, captchaInput); err != nil {
- data.ErrCaptcha = err.Error()
- return c.Render(http.StatusOK, "chat-create-room", data)
- }
- passwordHash := ""
- if data.Password != "" {
- passwordHash = database.GetRoomPasswordHash(data.Password)
- }
- if _, err := db.CreateRoom(data.RoomName, passwordHash, authUser.ID, data.IsListed); err != nil {
- data.Error = err.Error()
- return c.Render(http.StatusOK, "chat-create-room", data)
- }
- return c.Redirect(http.StatusFound, "/chat/"+data.RoomName)
- }
- return c.Render(http.StatusOK, "chat-create-room", data)
-}
-
func DonateHandler(c echo.Context) error {
return c.Render(http.StatusOK, "donate", nil)
}
@@ -1420,138 +1356,6 @@ func ShopHandler(c echo.Context) error {
return c.Render(http.StatusOK, "shop", data)
}
-func ChatDeleteHandler(c echo.Context) error {
- authUser := c.Get("authUser").(*database.User)
- db := c.Get("database").(*database.DkfDB)
- var data chatDeleteData
- roomName := c.Param("roomName")
- room, err := db.GetChatRoomByName(roomName)
- if err != nil {
- return c.Redirect(http.StatusFound, "/")
- }
- if !room.IsRoomOwner(*authUser) {
- return c.Redirect(http.StatusFound, "/")
- }
- data.Room = room
-
- if c.Request().Method == http.MethodPost {
- if room.IsProtected() {
- hutils.DeleteRoomCookie(c, int64(room.ID))
- }
- db.DeleteChatRoomByID(room.ID)
- return c.Redirect(http.StatusFound, "/chat")
- }
-
- return c.Render(http.StatusOK, "chat-delete", data)
-}
-
-func ChatArchiveHandler(c echo.Context) error {
- authUser := c.Get("authUser").(*database.User)
- db := c.Get("database").(*database.DkfDB)
- var data chatArchiveData
- data.DateFormat = authUser.GetDateFormat()
- roomName := c.Param("roomName")
-
- room, roomKey, err := dutils.GetRoomAndKey(db, c, roomName)
- if err != nil {
- return c.Redirect(http.StatusFound, "/chat")
- }
-
- data.UUID = c.QueryParam("uuid")
- data.Room = room
-
- if data.UUID != "" {
- msg, err := db.GetRoomChatMessageByUUID(room.ID, data.UUID)
- if err != nil {
- return c.Redirect(http.StatusFound, "/")
- }
- nbMsg := 150
- args := []any{room.ID, authUser.ID, authUser.ID}
- whereClause := `room_id = ? AND group_id IS NULL AND (to_user_id is null OR to_user_id = ? OR user_id = ?)`
- if !authUser.DisplayIgnored {
- args = append(args, authUser.ID)
- whereClause += ` AND user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)`
- }
- raw := `
- SELECT * FROM (
- SELECT *
- FROM chat_messages
- WHERE ` + whereClause + `
- AND id >= ?
- ORDER BY id ASC
- LIMIT ?
- )
- UNION
- SELECT * FROM (
- SELECT *
- FROM chat_messages
- WHERE ` + whereClause + `
- AND id < ?
- ORDER BY id DESC
- LIMIT ?
- ) ORDER BY id DESC`
- args = append(args, msg.ID, nbMsg)
- args = append(args, args...)
- db.DB().Raw(raw, args...).Scan(&data.Messages)
-
- // Manually do Preload("Room")
- for _, m := range data.Messages {
- m.Room = data.Room
- }
-
- //--- < Manually do a Preload("User") Preload("ToUser") > ---
- usersIDs := hashset.New[database.UserID]()
- for _, m := range data.Messages {
- usersIDs.Insert(m.UserID)
- if m.ToUserID != nil {
- usersIDs.Insert(*m.ToUserID)
- }
- }
- users, _ := db.GetUsersByID(usersIDs.ToArray())
- usersMap := make(map[database.UserID]database.User)
- for _, u := range users {
- usersMap[u.ID] = u
- }
- for i, m := range data.Messages {
- if u, ok := usersMap[m.UserID]; ok {
- data.Messages[i].User = u
- }
- if m.ToUserID != nil {
- if u, ok := usersMap[*m.ToUserID]; ok {
- data.Messages[i].ToUser = &u
- }
- }
- }
- //--- </ Manually do a Preload("User") Preload("ToUser") > ---
-
- } else {
- if err := db.DB().Table("chat_messages").
- Where("room_id = ? AND group_id IS NULL AND (to_user_id is null OR to_user_id = ? OR user_id = ?)", room.ID, authUser.ID, authUser.ID).
- Scopes(func(query *gorm.DB) *gorm.DB {
- if !authUser.DisplayIgnored {
- query = query.Where(`user_id NOT IN (SELECT ignored_user_id FROM ignored_users WHERE user_id = ?)`, authUser.ID)
- }
- data.CurrentPage, data.MaxPage, data.MessagesCount, query = NewPaginator().SetResultPerPage(300).Paginate(c, query)
- return query
- }).
- Order("id DESC").
- Preload("Room").
- Preload("User").
- Preload("ToUser").
- Find(&data.Messages).Error; err != nil {
- logrus.Error(err)
- }
- }
-
- if roomKey != "" {
- if err := data.Messages.DecryptAll(roomKey); err != nil {
- return c.NoContent(http.StatusInternalServerError)
- }
- }
-
- return c.Render(http.StatusOK, "chat-archive", data)
-}
-
type ValueTokenCache struct {
Value string // Either age/pgp token or msg to sign
PKey string // age/pgp public key
@@ -2579,38 +2383,3 @@ Loop:
c.Response().Flush()
return nil
}
-
-func ChatCodeHandler(c echo.Context) error {
- messageUUID := c.Param("messageUUID")
- idx, err := strconv.Atoi(c.Param("idx"))
- if err != nil {
- return c.Redirect(http.StatusFound, "/")
- }
-
- authUser := c.Get("authUser").(*database.User)
- db := c.Get("database").(*database.DkfDB)
- msg, err := db.GetChatMessageByUUID(messageUUID)
- if err != nil {
- return c.Redirect(http.StatusFound, "/")
- }
-
- if !verifyMsgAuth(db, authUser, &msg) {
- return c.Redirect(http.StatusFound, "/")
- }
-
- doc, err := goquery.NewDocumentFromReader(strings.NewReader(msg.Message))
- if err != nil {
- return c.Redirect(http.StatusFound, "/")
- }
- n := doc.Find("pre").Eq(idx)
- if n == nil {
- return c.Redirect(http.StatusFound, "/")
- }
-
- var data chatCodepData
- data.Code, err = n.Html()
- if err != nil {
- return c.Redirect(http.StatusFound, "/")
- }
- return c.Render(http.StatusOK, "chat-code", data)
-}