2026-07-17 10:53:08 +08:00
|
|
|
package server
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"log/slog"
|
|
|
|
|
"net/http"
|
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
|
|
|
|
"github.com/yyc12345/coconut-leaf/backend/config"
|
|
|
|
|
"github.com/yyc12345/coconut-leaf/backend/database"
|
|
|
|
|
"github.com/yyc12345/coconut-leaf/backend/utils"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ResponseBody is the JSON envelope returned by every API endpoint, mirroring
|
|
|
|
|
// the legacy ConstructResponseBody: {success, error, data}.
|
|
|
|
|
type ResponseBody struct {
|
|
|
|
|
Success bool `json:"success"`
|
|
|
|
|
Error string `json:"error"`
|
|
|
|
|
Data any `json:"data"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handler holds the shared dependencies injected into every Gin handler: the
|
|
|
|
|
// database, the application logger and the loaded config.
|
|
|
|
|
type Handler struct {
|
|
|
|
|
DB database.Database
|
|
|
|
|
Logger *slog.Logger
|
|
|
|
|
Cfg *config.Config
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// region: Utilities
|
|
|
|
|
|
|
|
|
|
// respond wraps a (data, error) pair into a ResponseBody. The HTTP status is
|
|
|
|
|
// always 200; failures are encoded in the body, mirroring the legacy API.
|
|
|
|
|
func respond(c *gin.Context, data any, err error) {
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.JSON(http.StatusOK, ResponseBody{Success: false, Error: err.Error()})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.JSON(http.StatusOK, ResponseBody{Success: true, Data: data})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// respondInvalidParam replies with the legacy "Invalid parameter" body.
|
|
|
|
|
func respondInvalidParam(c *gin.Context) {
|
|
|
|
|
c.JSON(http.StatusOK, ResponseBody{Success: false, Error: "Invalid parameter"})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fetchForm flattens the POST form into a map and logs it at debug level,
|
|
|
|
|
// mirroring the legacy SmartDbCaller "User Form" log.
|
|
|
|
|
func fetchForm(c *gin.Context, logger *slog.Logger) map[string]string {
|
|
|
|
|
_ = c.Request.ParseForm()
|
|
|
|
|
form := make(map[string]string, len(c.Request.PostForm))
|
|
|
|
|
for k, v := range c.Request.PostForm {
|
|
|
|
|
if len(v) > 0 {
|
|
|
|
|
form[k] = v[0]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
logger.Debug("User Form", "form", form)
|
|
|
|
|
return form
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fetchClientInfo returns the client user agent and IP, mirroring the legacy
|
|
|
|
|
// FetchClientNetworkInfo. The real IP (X-Forwarded-For behind Nginx) comes from
|
|
|
|
|
// gin's c.ClientIP().
|
|
|
|
|
func fetchClientInfo(c *gin.Context) (ua, ip string) {
|
|
|
|
|
ua = c.Request.UserAgent()
|
|
|
|
|
ip = c.ClientIP()
|
|
|
|
|
if ip == "" {
|
|
|
|
|
ip = "0.0.0.0"
|
|
|
|
|
}
|
|
|
|
|
return ua, ip
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// Run sets up the Gin engine with all routes bound to the handler and starts
|
|
|
|
|
// listening on the configured web port.
|
|
|
|
|
func Run(handler *Handler) error {
|
2026-07-17 12:12:14 +08:00
|
|
|
if handler.Cfg.Others.Debug {
|
|
|
|
|
gin.SetMode(gin.DebugMode)
|
|
|
|
|
} else {
|
|
|
|
|
gin.SetMode(gin.ReleaseMode)
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-17 10:53:08 +08:00
|
|
|
r := gin.Default()
|
2026-07-17 12:12:14 +08:00
|
|
|
|
|
|
|
|
err := r.SetTrustedProxies([]string{
|
|
|
|
|
"127.0.0.1", // IPv4 本地回环
|
|
|
|
|
"::1", // IPv6 本地回环
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-17 10:53:08 +08:00
|
|
|
registerRoutes(r, handler)
|
|
|
|
|
return r.Run(fmt.Sprintf(":%d", handler.Cfg.Web.Port))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func registerRoutes(r *gin.Engine, h *Handler) {
|
|
|
|
|
// common
|
|
|
|
|
r.POST("/common/salt", h.CommonSalt)
|
|
|
|
|
r.POST("/common/login", h.CommonLogin)
|
|
|
|
|
r.POST("/common/webLogin", h.CommonWebLogin)
|
|
|
|
|
r.POST("/common/logout", h.CommonLogout)
|
|
|
|
|
r.POST("/common/tokenValid", h.CommonTokenValid)
|
|
|
|
|
|
|
|
|
|
// calendar
|
|
|
|
|
r.POST("/calendar/getFull", h.CalendarGetFull)
|
|
|
|
|
r.POST("/calendar/getList", h.CalendarGetList)
|
|
|
|
|
r.POST("/calendar/getDetail", h.CalendarGetDetail)
|
|
|
|
|
r.POST("/calendar/update", h.CalendarUpdate)
|
|
|
|
|
r.POST("/calendar/add", h.CalendarAdd)
|
|
|
|
|
r.POST("/calendar/delete", h.CalendarDelete)
|
|
|
|
|
|
|
|
|
|
// collection
|
|
|
|
|
r.POST("/collection/getFullOwn", h.CollectionGetFullOwn)
|
|
|
|
|
r.POST("/collection/getListOwn", h.CollectionGetListOwn)
|
|
|
|
|
r.POST("/collection/getDetailOwn", h.CollectionGetDetailOwn)
|
|
|
|
|
r.POST("/collection/addOwn", h.CollectionAddOwn)
|
|
|
|
|
r.POST("/collection/updateOwn", h.CollectionUpdateOwn)
|
|
|
|
|
r.POST("/collection/deleteOwn", h.CollectionDeleteOwn)
|
|
|
|
|
r.POST("/collection/getSharing", h.CollectionGetSharing)
|
|
|
|
|
r.POST("/collection/deleteSharing", h.CollectionDeleteSharing)
|
|
|
|
|
r.POST("/collection/addSharing", h.CollectionAddSharing)
|
|
|
|
|
r.POST("/collection/getShared", h.CollectionGetShared)
|
|
|
|
|
|
|
|
|
|
// todo
|
|
|
|
|
r.POST("/todo/getFull", h.TodoGetFull)
|
|
|
|
|
r.POST("/todo/getList", h.TodoGetList)
|
|
|
|
|
r.POST("/todo/getDetail", h.TodoGetDetail)
|
|
|
|
|
r.POST("/todo/add", h.TodoAdd)
|
|
|
|
|
r.POST("/todo/update", h.TodoUpdate)
|
|
|
|
|
r.POST("/todo/delete", h.TodoDelete)
|
|
|
|
|
|
|
|
|
|
// admin
|
|
|
|
|
r.POST("/admin/get", h.AdminGet)
|
|
|
|
|
r.POST("/admin/add", h.AdminAdd)
|
|
|
|
|
r.POST("/admin/update", h.AdminUpdate)
|
|
|
|
|
r.POST("/admin/delete", h.AdminDelete)
|
|
|
|
|
|
|
|
|
|
// profile
|
|
|
|
|
r.POST("/profile/isAdmin", h.ProfileIsAdmin)
|
|
|
|
|
r.POST("/profile/changePassword", h.ProfileChangePassword)
|
|
|
|
|
r.POST("/profile/getToken", h.ProfileGetToken)
|
|
|
|
|
r.POST("/profile/deleteToken", h.ProfileDeleteToken)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// region: API Route
|
|
|
|
|
|
|
|
|
|
// region: Common
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CommonSalt(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
username, ok := form["username"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CommonSalt(c.Request.Context(), username)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CommonLogin(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
username, okU := form["username"]
|
|
|
|
|
password, okP := form["password"]
|
|
|
|
|
if !okU || !okP {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
clientUa, clientIp := fetchClientInfo(c)
|
|
|
|
|
data, err := h.DB.CommonLogin(c.Request.Context(), username, password, clientUa, clientIp)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CommonWebLogin(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
username, okU := form["username"]
|
|
|
|
|
password, okP := form["password"]
|
|
|
|
|
if !okU || !okP {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
clientUa, clientIp := fetchClientInfo(c)
|
|
|
|
|
data, err := h.DB.CommonWebLogin(c.Request.Context(), username, password, clientUa, clientIp)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CommonLogout(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CommonLogout(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CommonTokenValid(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CommonTokenValid(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// region: Calendar
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CalendarGetFull(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
sds, okS := form["startDateTime"]
|
|
|
|
|
eds, okE := form["endDateTime"]
|
|
|
|
|
if !okT || !okS || !okE {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
startDateTime, err1 := strconv.ParseInt(sds, 10, 64)
|
|
|
|
|
endDateTime, err2 := strconv.ParseInt(eds, 10, 64)
|
|
|
|
|
if err1 != nil || err2 != nil {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CalendarGetFull(c.Request.Context(), token, startDateTime, endDateTime)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CalendarGetList(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
sds, okS := form["startDateTime"]
|
|
|
|
|
eds, okE := form["endDateTime"]
|
|
|
|
|
if !okT || !okS || !okE {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
startDateTime, err1 := strconv.ParseInt(sds, 10, 64)
|
|
|
|
|
endDateTime, err2 := strconv.ParseInt(eds, 10, 64)
|
|
|
|
|
if err1 != nil || err2 != nil {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CalendarGetList(c.Request.Context(), token, startDateTime, endDateTime)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CalendarGetDetail(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
if !okT || !okU {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CalendarGetDetail(c.Request.Context(), token, uuid)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CalendarUpdate(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var opts database.CalendarUpdateOptions
|
|
|
|
|
provided := 0
|
|
|
|
|
if v, ok := form["belongTo"]; ok {
|
|
|
|
|
opts.BelongTo = &v
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if v, ok := form["title"]; ok {
|
|
|
|
|
opts.Title = &v
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if v, ok := form["description"]; ok {
|
|
|
|
|
opts.Description = &v
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if v, ok := form["eventDateTimeStart"]; ok {
|
|
|
|
|
n, err := strconv.ParseInt(v, 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
opts.EventDateTimeStart = &n
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if v, ok := form["eventDateTimeEnd"]; ok {
|
|
|
|
|
n, err := strconv.ParseInt(v, 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
opts.EventDateTimeEnd = &n
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if v, ok := form["loopRules"]; ok {
|
|
|
|
|
opts.LoopRules = &v
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if v, ok := form["timezoneOffset"]; ok {
|
|
|
|
|
n, err := strconv.ParseInt(v, 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
opts.TimezoneOffset = &n
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if provided == 0 {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data, err := h.DB.CalendarUpdate(c.Request.Context(), token, uuid, lastChange, opts)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CalendarAdd(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
belongTo, okB := form["belongTo"]
|
|
|
|
|
title, okTi := form["title"]
|
|
|
|
|
description, okD := form["description"]
|
|
|
|
|
loopRules, okL := form["loopRules"]
|
|
|
|
|
edtsStr, okES := form["eventDateTimeStart"]
|
|
|
|
|
edteStr, okEE := form["eventDateTimeEnd"]
|
|
|
|
|
tzoStr, okTZ := form["timezoneOffset"]
|
|
|
|
|
if !okT || !okB || !okTi || !okD || !okL || !okES || !okEE || !okTZ {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
edts, err1 := strconv.ParseInt(edtsStr, 10, 64)
|
|
|
|
|
edte, err2 := strconv.ParseInt(edteStr, 10, 64)
|
|
|
|
|
tzo, err3 := strconv.ParseInt(tzoStr, 10, 64)
|
|
|
|
|
if err1 != nil || err2 != nil || err3 != nil {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CalendarAdd(c.Request.Context(), token, belongTo, title, description, edts, edte, loopRules, tzo)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CalendarDelete(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CalendarDelete(c.Request.Context(), token, uuid, lastChange)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// region: Collection
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionGetFullOwn(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionGetFullOwn(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionGetListOwn(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionGetListOwn(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionGetDetailOwn(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
if !okT || !okU {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionGetDetailOwn(c.Request.Context(), token, uuid)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionAddOwn(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
name, okN := form["name"]
|
|
|
|
|
if !okT || !okN {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionAddOwn(c.Request.Context(), token, name)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionUpdateOwn(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
name, okN := form["name"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okN || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionUpdateOwn(c.Request.Context(), token, uuid, name, lastChange)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionDeleteOwn(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionDeleteOwn(c.Request.Context(), token, uuid, lastChange)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionGetSharing(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
if !okT || !okU {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionGetSharing(c.Request.Context(), token, uuid)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionDeleteSharing(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
target, okG := form["target"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okG || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionDeleteSharing(c.Request.Context(), token, uuid, target, lastChange)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionAddSharing(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
target, okG := form["target"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okG || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionAddSharing(c.Request.Context(), token, uuid, target, lastChange)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CollectionGetShared(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.CollectionGetShared(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// region: Todo
|
|
|
|
|
|
|
|
|
|
func (h *Handler) TodoGetFull(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.TodoGetFull(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) TodoGetList(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.TodoGetList(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) TodoGetDetail(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
if !okT || !okU {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.TodoGetDetail(c.Request.Context(), token, uuid)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) TodoAdd(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.TodoAdd(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) TodoUpdate(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
dataField, okD := form["data"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okD || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.TodoUpdate(c.Request.Context(), token, uuid, dataField, lastChange)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) TodoDelete(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
uuid, okU := form["uuid"]
|
|
|
|
|
lastChange, okL := form["lastChange"]
|
|
|
|
|
if !okT || !okU || !okL {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.TodoDelete(c.Request.Context(), token, uuid, lastChange)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// region: Admin
|
|
|
|
|
|
|
|
|
|
func (h *Handler) AdminGet(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.AdminGet(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) AdminAdd(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
username, okU := form["username"]
|
|
|
|
|
if !okT || !okU {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.AdminAdd(c.Request.Context(), token, username)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) AdminUpdate(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
username, okU := form["username"]
|
|
|
|
|
if !okT || !okU {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var opts database.AdminUpdateOptions
|
|
|
|
|
provided := 0
|
|
|
|
|
if v, ok := form["password"]; ok {
|
|
|
|
|
opts.Password = &v
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if v, ok := form["isAdmin"]; ok {
|
|
|
|
|
b := utils.Str2Bool(v)
|
|
|
|
|
opts.IsAdmin = &b
|
|
|
|
|
provided++
|
|
|
|
|
}
|
|
|
|
|
if provided == 0 {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data, err := h.DB.AdminUpdate(c.Request.Context(), token, username, opts)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) AdminDelete(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
username, okU := form["username"]
|
|
|
|
|
if !okT || !okU {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.AdminDelete(c.Request.Context(), token, username)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// region: Profile
|
|
|
|
|
|
|
|
|
|
func (h *Handler) ProfileIsAdmin(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.ProfileIsAdmin(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) ProfileChangePassword(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
password, okP := form["password"]
|
|
|
|
|
if !okT || !okP {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.ProfileChangePassword(c.Request.Context(), token, password)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) ProfileGetToken(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, ok := form["token"]
|
|
|
|
|
if !ok {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.ProfileGetToken(c.Request.Context(), token)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) ProfileDeleteToken(c *gin.Context) {
|
|
|
|
|
form := fetchForm(c, h.Logger)
|
|
|
|
|
token, okT := form["token"]
|
|
|
|
|
deleteToken, okD := form["deleteToken"]
|
|
|
|
|
if !okT || !okD {
|
|
|
|
|
respondInvalidParam(c)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := h.DB.ProfileDeleteToken(c.Request.Context(), token, deleteToken)
|
|
|
|
|
respond(c, data, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// endregion
|