+++ /dev/null
-package auth
"encoding/json"
"fmt"
"io"
+ "log"
"net/http"
"os"
google_oauth_config.RedirectURL = OAUTH_JSON.Web.RedirectUris[1]
}
- fmt.Println(google_oauth_config.RedirectURL)
+ log.Println(google_oauth_config.RedirectURL)
return google_oauth_config
"github.com/gin-gonic/gin"
)
-func Is0(c *gin.Context) bool {
+func Is0(c *gin.Context, userId *string, sessionId *string) bool {
session := sessions.Default(c)
return false
}
+ if userId != nil {
+ *userId = s.Id
+ }
+
+ if sessionId != nil {
+
+ *sessionId = session_id
+ }
+
return true
}
"unicode"
)
+func VerifyDefaultValue(raw string) bool {
+
+ for _, c := range raw {
+
+ if unicode.IsLower(c) {
+
+ continue
+
+ } else if unicode.IsDigit(c) {
+
+ continue
+
+ } else if c == '-' {
+
+ } else {
+
+ return false
+ }
+
+ }
+
+ return true
+}
+
func VerifyMediaKey(mediakey string) bool {
mklist := strings.SplitN(mediakey, ".", 2)
+ if len(mklist) != 2 {
+ return false
+ }
+
for _, c := range mklist[0] {
if unicode.IsLetter(c) {
package db
import (
- "encoding/json"
"fmt"
"mime/multipart"
"os"
- "strings"
"github.com/gin-gonic/gin"
)
return nil
}
-
-func GetAssociateMediaKeysForEditorjsSrc(rawContent string) ([]string, error) {
-
- var retlist []string
-
- var editorjsSrc map[string]interface{}
-
- rawContentBytes := []byte(rawContent)
-
- err := json.Unmarshal(rawContentBytes, &editorjsSrc)
-
- if err != nil {
-
- return nil, fmt.Errorf("failed to unmarshal: %s", err.Error())
-
- }
-
- blocks, okay := editorjsSrc["blocks"]
-
- if !okay {
-
- return nil, fmt.Errorf("invalid format: %s", "no blocks")
- }
-
- blocksList := blocks.([]interface{})
-
- blocksLen := len(blocksList)
-
- for i := 0; i < blocksLen; i++ {
-
- blockObj := blocksList[i].(map[string]interface{})
-
- objType, okay := blockObj["type"]
-
- if !okay {
- continue
- }
-
- if objType != "image" {
- continue
- }
-
- objData, okay := blockObj["data"]
-
- if !okay {
- continue
- }
-
- objFields := objData.(map[string]interface{})
-
- fileField, okay := objFields["file"]
-
- if !okay {
- continue
- }
-
- targetProps := fileField.(map[string]interface{})
-
- urlTarget, okay := targetProps["url"]
-
- if !okay {
- continue
- }
-
- target := urlTarget.(string)
-
- pathList := strings.Split(target, "/")
-
- keyExt := pathList[len(pathList)-1]
-
- keyExtList := strings.Split(keyExt, ".")
-
- key := keyExtList[0]
-
- retlist = append(retlist, key)
- }
-
- return retlist, nil
-}
package db
-import "fmt"
+import (
+ "fmt"
+ "log"
+)
type Story struct {
StoryId int
}
-func DeleteStoryByTitle(title string) (*Story, error) {
+func DeleteStoryById(id string) error {
- story, err := GetStoryByTitle(title)
+ story, err := GetStoryById(id)
if err != nil {
- return nil, fmt.Errorf("failed to get story by title")
+ return fmt.Errorf("failed to get story by id")
+ }
+
+ keys, err := GetAssociateMediaKeysForEditorjsSrc([]byte(story.Content))
+
+ if err != nil {
+
+ return fmt.Errorf("failed to get story media keys by id: %v", err)
}
q := `
err = exec(q, a)
if err != nil {
- return nil, fmt.Errorf("failed to delete story record")
+ return fmt.Errorf("failed to delete story record")
+ }
+
+ keysLen := len(keys)
+
+ for i := 0; i < keysLen; i++ {
+
+ err = DeleteMedia(keys[i])
+
+ if err != nil {
+
+ log.Printf("failed to delete media key: %s\n", err.Error())
+ }
+
+ }
+
+ return nil
+
+}
+
+func GetAllStory() ([]Story, error) {
+
+ stories := []Story{}
+
+ q := `
+
+ SELECT
+ *
+ FROM
+ story
+ `
+
+ a := []any{}
+
+ res, err := query(q, a)
+
+ if err != nil {
+
+ return nil, fmt.Errorf("failed to get all story: %v", err)
+ }
+
+ defer res.Close()
+
+ for res.Next() {
+
+ story := Story{}
+
+ err = res.Scan(
+
+ &story.Id,
+ &story.Title,
+ &story.DateMarked,
+ &story.PrimaryMediaName,
+ )
+
+ if err != nil {
+ return nil, fmt.Errorf("failed to get story record: %v", err)
+ }
+
+ stories = append(stories, story)
+
}
- return story, nil
+ return stories, nil
}
--- /dev/null
+package db
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+func GetAssociateMediaKeysForEditorjsSrc(rawArticle []byte) ([]string, error) {
+
+ var retlist []string
+
+ var editorjsSrc map[string]interface{}
+
+ err := json.Unmarshal(rawArticle, &editorjsSrc)
+
+ if err != nil {
+
+ return nil, fmt.Errorf("failed to unmarshal: %s", err.Error())
+
+ }
+
+ blocks, okay := editorjsSrc["blocks"]
+
+ if !okay {
+
+ return nil, fmt.Errorf("invalid format: %s", "no blocks")
+ }
+
+ blocksList := blocks.([]interface{})
+
+ blocksLen := len(blocksList)
+
+ for i := 0; i < blocksLen; i++ {
+
+ blockObj := blocksList[i].(map[string]interface{})
+
+ objType, okay := blockObj["type"]
+
+ if !okay {
+ continue
+ }
+
+ if objType != "image" {
+ continue
+ }
+
+ objData, okay := blockObj["data"]
+
+ if !okay {
+ continue
+ }
+
+ objFields := objData.(map[string]interface{})
+
+ fileField, okay := objFields["file"]
+
+ if !okay {
+ continue
+ }
+
+ targetProps := fileField.(map[string]interface{})
+
+ urlTarget, okay := targetProps["url"]
+
+ if !okay {
+ continue
+ }
+
+ target := urlTarget.(string)
+
+ pathList := strings.Split(target, "/")
+
+ key := pathList[len(pathList)-1]
+
+ retlist = append(retlist, key)
+ }
+
+ return retlist, nil
+}
package api
-import (
- "encoding/json"
- "fmt"
- "log"
- "net/http"
-
- pkgauth "our-wedding-rsvp/pkg/auth"
- pkgdb "our-wedding-rsvp/pkg/db"
-
- "github.com/gin-gonic/contrib/sessions"
- "github.com/gin-gonic/gin"
-)
-
type CLIENT_REQ struct {
Data string `json:"data"`
}
Status string `json:"status"`
Reply string `json:"reply"`
}
-
-func OauthGoogleLogin(c *gin.Context) {
-
- if pkgauth.Is0(c) {
-
- log.Printf("oauth login: already logged in\n")
-
- c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "already logged in"})
-
- return
-
- }
-
- oauth_state := pkgauth.GenerateStateAuthCookie(c)
-
- u := pkgauth.GoogleOauthConfig.AuthCodeURL(oauth_state)
-
- c.Redirect(302, u)
-
-}
-
-func OauthGoogleCallback(c *gin.Context) {
-
- if pkgauth.Is0(c) {
-
- fmt.Printf("oauth callback: already logged in\n")
-
- c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "already logged in"})
-
- return
-
- }
-
- session := sessions.Default(c)
-
- var session_id string
-
- v := session.Get("RSVP")
-
- if v == nil {
- log.Printf("access auth failed: %s\n", "session id not found")
- return
- } else {
- session_id = v.(string)
- }
-
- state := c.Request.FormValue("state")
-
- if state == "" {
- log.Printf("access auth failed: %s\n", "form state not found")
- return
- }
-
- if state != session_id {
- log.Printf("access auth failed: %s\n", "value not matching")
- c.Redirect(302, "/")
- return
- }
-
- data, err := pkgauth.GetUserDataFromGoogle(c.Request.FormValue("code"))
- if err != nil {
- log.Printf("access auth failed: %s\n", err.Error())
- c.Redirect(302, "/")
- return
- }
-
- var oauth_struct pkgauth.OAuthStruct
-
- err = json.Unmarshal(data, &oauth_struct)
-
- if err != nil {
- log.Printf("access auth failed: %s\n", err.Error())
- c.Redirect(302, "/")
- return
- }
-
- if !oauth_struct.VERIFIED_EMAIL {
- log.Printf("access auth failed: %s\n", err.Error())
- c.Redirect(302, "/")
- return
- }
-
- if err != nil {
- log.Printf("access auth failed: %s\n", err.Error())
- c.Redirect(302, "/")
- return
- }
-
- as, err := pkgdb.GetAdminById(oauth_struct.EMAIL)
-
- if as == nil {
-
- log.Printf("access auth failed: %s", err.Error())
-
- c.Redirect(302, "/")
-
- return
-
- }
-
- err = pkgdb.SetAdminSessionId(oauth_struct.EMAIL, session_id, true)
-
- if err != nil {
-
- log.Printf("make session failed for admin: %s", err.Error())
-
- c.Redirect(302, "/")
-
- return
-
- }
-
- log.Println("oauth sign in success")
-
- c.Redirect(302, "/")
-
-}
--- /dev/null
+package api
+
+import (
+ "encoding/json"
+ "log"
+ "net/http"
+
+ pkgauth "our-wedding-rsvp/pkg/auth"
+ pkgdb "our-wedding-rsvp/pkg/db"
+
+ "github.com/gin-gonic/contrib/sessions"
+ "github.com/gin-gonic/gin"
+)
+
+type UserLogin struct {
+ Id string `json:"id"`
+ Passphrase string `json:"passphrase"`
+}
+
+func OauthGoogleLogin(c *gin.Context) {
+
+ if pkgauth.Is0(c, nil, nil) {
+
+ log.Printf("oauth login: already logged in\n")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "already logged in"})
+
+ return
+
+ }
+
+ oauth_state := pkgauth.GenerateStateAuthCookie(c)
+
+ u := pkgauth.GoogleOauthConfig.AuthCodeURL(oauth_state)
+
+ c.Redirect(302, u)
+
+}
+
+func OauthGoogleCallback(c *gin.Context) {
+
+ if pkgauth.Is0(c, nil, nil) {
+
+ log.Printf("oauth callback: already logged in\n")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "already logged in"})
+
+ return
+
+ }
+
+ session := sessions.Default(c)
+
+ var session_id string
+
+ v := session.Get("RSVP")
+
+ if v == nil {
+ log.Printf("access auth failed: %s\n", "session id not found")
+ return
+ } else {
+ session_id = v.(string)
+ }
+
+ state := c.Request.FormValue("state")
+
+ if state == "" {
+ log.Printf("access auth failed: %s\n", "form state not found")
+ return
+ }
+
+ if state != session_id {
+ log.Printf("access auth failed: %s\n", "value not matching")
+ c.Redirect(302, "/")
+ return
+ }
+
+ data, err := pkgauth.GetUserDataFromGoogle(c.Request.FormValue("code"))
+ if err != nil {
+ log.Printf("access auth failed: %s\n", err.Error())
+ c.Redirect(302, "/")
+ return
+ }
+
+ var oauth_struct pkgauth.OAuthStruct
+
+ err = json.Unmarshal(data, &oauth_struct)
+
+ if err != nil {
+ log.Printf("access auth failed: %s\n", err.Error())
+ c.Redirect(302, "/")
+ return
+ }
+
+ if !oauth_struct.VERIFIED_EMAIL {
+ log.Printf("access auth failed: %s\n", err.Error())
+ c.Redirect(302, "/")
+ return
+ }
+
+ if err != nil {
+ log.Printf("access auth failed: %s\n", err.Error())
+ c.Redirect(302, "/")
+ return
+ }
+
+ as, err := pkgdb.GetAdminById(oauth_struct.EMAIL)
+
+ if as == nil {
+
+ log.Printf("access auth failed: %s", err.Error())
+
+ c.Redirect(302, "/")
+
+ return
+
+ }
+
+ err = pkgdb.SetAdminSessionId(oauth_struct.EMAIL, session_id, true)
+
+ if err != nil {
+
+ log.Printf("make session failed for admin: %s", err.Error())
+
+ c.Redirect(302, "/")
+
+ return
+
+ }
+
+ log.Println("oauth sign in success")
+
+ c.Redirect(302, "/")
+
+}
+
+func Login(c *gin.Context) {
+
+ if pkgauth.USE_OAUTH2 {
+ log.Printf("user login: use oauth2\n")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid"})
+
+ return
+ }
+
+ var req CLIENT_REQ
+
+ var u_login UserLogin
+
+ if err := c.BindJSON(&req); err != nil {
+
+ log.Printf("user login: failed to bind: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+ }
+
+ err := json.Unmarshal([]byte(req.Data), &u_login)
+
+ if err != nil {
+
+ log.Printf("user login: failed to unmarshal: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ if !pkgauth.VerifyDefaultValue(u_login.Id) {
+
+ log.Printf("user login: not valid id: %s\n", u_login.Id)
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+ }
+
+ us, err := pkgdb.GetAdminById(u_login.Id)
+
+ if err != nil {
+
+ log.Printf("user login: failed to get from user: %s\n", err.Error())
+
+ c.JSON(http.StatusForbidden, SERVER_RESP{Status: "error", Reply: "id doesn't exist"})
+
+ return
+ }
+
+ if !us.Pw.Valid {
+ log.Printf("user login: failed to get admin pw: null\n")
+
+ c.JSON(http.StatusForbidden, SERVER_RESP{Status: "error", Reply: "id invalid"})
+
+ return
+ }
+
+ if us.Pw.String != u_login.Passphrase {
+
+ log.Printf("user login: passphrase: %s", "not matching")
+
+ c.JSON(http.StatusForbidden, SERVER_RESP{Status: "error", Reply: "passphrase not matching"})
+
+ return
+
+ }
+
+ session_key := pkgauth.GenerateStateAuthCookie(c)
+
+ err = pkgdb.SetAdminSessionId(us.Id, session_key, true)
+
+ if err != nil {
+
+ log.Printf("user login: failed to set session: %s", err.Error())
+
+ c.JSON(http.StatusInternalServerError, SERVER_RESP{Status: "error", Reply: "failed to login"})
+
+ return
+
+ }
+
+ c.JSON(http.StatusOK, SERVER_RESP{Status: "success", Reply: "logged in"})
+
+}
--- /dev/null
+package api
+
+import (
+ "encoding/json"
+ "log"
+ "net/http"
+ "strings"
+
+ "github.com/gin-gonic/gin"
+
+ pkgauth "our-wedding-rsvp/pkg/auth"
+ pkgdb "our-wedding-rsvp/pkg/db"
+ pkgutils "our-wedding-rsvp/pkg/utils"
+)
+
+type ArticleInfo struct {
+ Id string `json:"id,omitempty"`
+ Title string `json:"title"`
+ Content string `json:"content,omitempty"`
+ DateMarked string `json:"dateMarked"`
+ PrimaryMediaName string `json:"primaryMediaName"`
+}
+
+func UploadStory(c *gin.Context) {
+
+ if !pkgauth.Is0(c, nil, nil) {
+
+ log.Printf("article upload: not admin\n")
+
+ c.JSON(http.StatusForbidden, SERVER_RESP{Status: "error", Reply: "you're not admin"})
+
+ return
+
+ }
+
+ var req CLIENT_REQ
+
+ var a_info ArticleInfo
+
+ if err := c.BindJSON(&req); err != nil {
+
+ log.Printf("article upload: failed to bind: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+ }
+
+ err := json.Unmarshal([]byte(req.Data), &a_info)
+
+ if err != nil {
+
+ log.Printf("article upload: failed to unmarshal: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ if a_info.Title == "" {
+
+ log.Printf("article upload: needs title\n")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ if a_info.Content == "" {
+
+ log.Printf("article upload: needs content\n")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ if a_info.DateMarked == "" {
+
+ log.Printf("article upload: needs dateMarked\n")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ if a_info.PrimaryMediaName == "" {
+
+ log.Printf("article upload: needs primaryMediaName\n")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ new_file_name, _ := pkgutils.GetRandomHex(32)
+
+ err = pkgdb.SaveStory(new_file_name, a_info.Title, a_info.DateMarked, a_info.PrimaryMediaName, a_info.Content)
+
+ if err != nil {
+
+ log.Printf("article upload: failed to upload: %s", err.Error())
+
+ c.JSON(http.StatusInternalServerError, SERVER_RESP{Status: "error", Reply: "failed to upload"})
+
+ return
+ }
+
+ c.JSON(http.StatusOK, SERVER_RESP{Status: "success", Reply: "uploaded"})
+
+}
+
+func DownloadStoryById(c *gin.Context) {
+
+ watchId := c.Param("storyId")
+
+ if !pkgauth.VerifyDefaultValue(watchId) {
+
+ log.Printf("get article: illegal: %s\n", watchId)
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ story, err := pkgdb.GetStoryById(watchId)
+
+ if err != nil {
+
+ log.Printf("failed to get article: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+ }
+
+ content := story.Content
+
+ c.JSON(http.StatusOK, SERVER_RESP{Status: "success", Reply: content})
+
+}
+
+func UploadStoryMedia(c *gin.Context) {
+
+ if !pkgauth.Is0(c, nil, nil) {
+
+ log.Printf("media upload: not admin\n")
+
+ c.JSON(http.StatusForbidden, SERVER_RESP{Status: "error", Reply: "you're not admin"})
+
+ return
+
+ }
+
+ file, _ := c.FormFile("file")
+
+ rawMediaType := file.Header.Get("Content-Type")
+
+ mediaProplist := strings.Split(rawMediaType, "/")
+
+ //mediaType := mediaProplist[0]
+ mediaExt := mediaProplist[1]
+
+ f_name := file.Filename
+
+ f_name_list := strings.Split(f_name, ".")
+
+ f_name_len := len(f_name_list)
+
+ if f_name_len < 1 {
+
+ log.Println("no extension specified")
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+ }
+
+ extension := f_name_list[f_name_len-1]
+
+ log.Printf("received: %s, size: %d, type: %s, ext: %s\n", file.Filename, file.Size, rawMediaType, extension)
+
+ file_name, _ := pkgutils.GetRandomHex(32)
+
+ err := pkgdb.UploadMedia(c, file, file_name)
+
+ if err != nil {
+
+ log.Println(err.Error())
+
+ c.JSON(http.StatusInternalServerError, SERVER_RESP{Status: "error", Reply: "failed to save"})
+
+ return
+
+ }
+
+ client_file_name := file_name + "." + mediaExt
+
+ c.JSON(http.StatusOK, SERVER_RESP{Status: "success", Reply: client_file_name})
+
+}
+
+func DownloadStoryMediaById(c *gin.Context) {
+
+ watchId := c.Param("mediaId")
+
+ if !pkgauth.VerifyMediaKey(watchId) {
+
+ log.Printf("download media: illegal: %s\n", watchId)
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ err := pkgdb.DownloadMedia(c, watchId)
+
+ if err != nil {
+
+ log.Printf("download media: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ log.Println("media download success")
+}
+
+func GetStoryList(c *gin.Context) {
+
+ articles := make([]ArticleInfo, 0)
+
+ stories, err := pkgdb.GetAllStory()
+
+ if err != nil {
+
+ log.Printf("all stories: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+
+ slen := len(stories)
+
+ for i := 0; i < slen; i++ {
+
+ article := ArticleInfo{
+ Id: stories[i].Id,
+ Title: stories[i].Title,
+ DateMarked: stories[i].DateMarked,
+ PrimaryMediaName: stories[i].PrimaryMediaName,
+ }
+
+ articles = append(articles, article)
+
+ }
+
+ abytes, err := json.Marshal(articles)
+
+ if err != nil {
+ log.Printf("all stories: marshal: %s\n", err.Error())
+
+ c.JSON(http.StatusBadRequest, SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+ }
+
+ c.JSON(http.StatusOK, SERVER_RESP{Status: "success", Reply: string(abytes)})
+
+}
e.GET("/signin", getSignin)
+ e.GET("/signout", Logout)
+
+ e.GET("/story/r/:storyId", getRead)
+
+ e.GET("/story/w", getWrite)
+
+ e.GET("/story/w/:storyId/delete", DeleteStory)
+
e.GET("/api/oauth2/google/signin", pkgserverapi.OauthGoogleLogin)
e.GET("/oauth2/google/callback", pkgserverapi.OauthGoogleCallback)
- e.GET("/story/r/:storyId", getRead)
+ e.POST("/api/signin", pkgserverapi.Login)
- e.GET("/story/w", getWrite)
+ e.POST("/api/story/upload", pkgserverapi.UploadStory)
+
+ e.POST("/api/story/download/:storyId", pkgserverapi.DownloadStoryById)
+
+ e.POST("/api/media/upload", pkgserverapi.UploadStoryMedia)
+
+ e.GET("/api/media/download/c/:mediaId", pkgserverapi.DownloadStoryMediaById)
+
+ e.GET("/api/story/list", pkgserverapi.GetStoryList)
return nil
}
package server
import (
+ "log"
+ "net/http"
+
"github.com/gin-gonic/gin"
pkgauth "our-wedding-rsvp/pkg/auth"
+ pkgdb "our-wedding-rsvp/pkg/db"
+ pkgserverapi "our-wedding-rsvp/pkg/server/api"
)
func getIndex(c *gin.Context) {
func getRead(c *gin.Context) {
- c.HTML(200, "read.html", gin.H{})
+ watchId := c.Param("storyId")
+
+ if !pkgauth.VerifyDefaultValue(watchId) {
+
+ log.Printf("get article: illegal: %s\n", watchId)
+
+ c.JSON(http.StatusBadRequest, pkgserverapi.SERVER_RESP{Status: "error", Reply: "invalid format"})
+
+ return
+
+ }
+ c.HTML(200, "read.html", gin.H{
+ "article_code": watchId,
+ })
+
}
func getWrite(c *gin.Context) {
- if !pkgauth.Is0(c) {
+ if !pkgauth.Is0(c, nil, nil) {
c.HTML(200, "index.html", gin.H{})
return
}
c.HTML(200, "write.html", gin.H{})
}
+
+func Logout(c *gin.Context) {
+
+ userId := ""
+
+ sessionId := ""
+
+ if !pkgauth.Is0(c, &userId, &sessionId) {
+
+ log.Printf("logout: not logged in\n")
+
+ c.JSON(http.StatusBadRequest, pkgserverapi.SERVER_RESP{Status: "error", Reply: "not logged in"})
+
+ return
+
+ }
+
+ err := pkgdb.SetAdminSessionId(userId, sessionId, false)
+
+ if err != nil {
+
+ log.Printf("logout: error: %v\n", err)
+
+ c.JSON(http.StatusBadRequest, pkgserverapi.SERVER_RESP{Status: "error", Reply: "invalid"})
+
+ return
+
+ }
+
+ c.JSON(http.StatusOK, pkgserverapi.SERVER_RESP{Status: "success", Reply: "logged out"})
+
+}
+
+func DeleteStory(c *gin.Context) {
+
+ if !pkgauth.Is0(c, nil, nil) {
+
+ log.Printf("delete: not allowed\n")
+
+ c.JSON(http.StatusBadRequest, pkgserverapi.SERVER_RESP{Status: "error", Reply: "invalid"})
+
+ return
+
+ }
+
+ storyId := c.Param("storyId")
+
+ err := pkgdb.DeleteStoryById(storyId)
+
+ if err != nil {
+ log.Printf("delete: error: %v\n", err)
+
+ c.JSON(http.StatusInternalServerError, pkgserverapi.SERVER_RESP{Status: "error", Reply: "internal error"})
+
+ return
+ }
+
+ c.JSON(http.StatusOK, pkgserverapi.SERVER_RESP{Status: "success", Reply: "deleted"})
+
+}
success: 1,
file: {
- url: '/api/media/c/' + data.reply,
+ url: '/api/media/download/c/' + data.reply,
}
}
<script src="https://cdn.jsdelivr.net/npm/@editorjs/inline-code@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/image@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
+ <script>
+ CONTENT_ID = "{{ .article_code }}"
+
+ </script>
</head>