diff options
author | FChannel <> | 2021-10-24 10:40:45 -0700 |
---|---|---|
committer | FChannel <> | 2022-06-19 12:53:29 -0700 |
commit | 48fefb76c0a908cc3fa00abc9c090ce3ac8cb560 (patch) | |
tree | a7a24aec9f43222949e1f004fd5cd8a247e5024e /main.go | |
parent | 65e79e6a743f447f320595dafec530212a568b9d (diff) |
gofiber conversion, index, board posts, board post hooked up
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 1455 |
1 files changed, 194 insertions, 1261 deletions
@@ -8,12 +8,16 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/gofrs/uuid" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/template/html" + // "github.com/gofrs/uuid" _ "github.com/lib/pq" + "html/template" - "io" + // "io" "io/ioutil" - "log" + // "log" "math/rand" "mime/multipart" "net/http" @@ -56,34 +60,36 @@ var ActorCache = make(map[string]Actor) var Themes []string +var DB *sql.DB + func main() { CreatedNeededDirectories() InitCache() - db := ConnectDB() + DB = ConnectDB() - defer db.Close() + defer DB.Close() - RunDatabaseSchema(db) + RunDatabaseSchema(DB) - go MakeCaptchas(db, 100) + go MakeCaptchas(DB, 100) *Key = CreateKey(32) - FollowingBoards = GetActorFollowingDB(db, Domain) + FollowingBoards = GetActorFollowingDB(DB, Domain) - go StartupArchive(db) + go StartupArchive(DB) - go CheckInactive(db) + go CheckInactive(DB) - Boards = GetBoardCollection(db) + Boards = GetBoardCollection(DB) // root actor is used to follow remote feeds that are not local //name, prefname, summary, auth requirements, restricted if GetConfigValue("instancename", "") != "" { - CreateNewBoardDB(db, *CreateNewActor("", GetConfigValue("instancename", ""), GetConfigValue("instancesummary", ""), authReq, false)) + CreateNewBoardDB(DB, *CreateNewActor("", GetConfigValue("instancename", ""), GetConfigValue("instancesummary", ""), authReq, false)) if PublicIndexing == "true" { AddInstanceToIndex(Domain) } @@ -108,1222 +114,172 @@ func main() { javascriptFiles := http.FileServer(http.Dir("./static")) http.Handle("/static/", http.StripPrefix("/static", neuter(javascriptFiles))) - // main routing - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - path := r.URL.Path - - // remove trailing slash - if path != "/" { - re := regexp.MustCompile(`/$`) - path = re.ReplaceAllString(path, "") - } - - var mainActor bool - var mainInbox bool - var mainOutbox bool - var mainFollowing bool - var mainFollowers bool - - var actorMain bool - var actorInbox bool - var actorCatalog bool - var actorOutbox bool - var actorPost bool - var actorFollowing bool - var actorFollowers bool - var actorReported bool - var actorVerification bool - var actorMainPage bool - var actorArchive bool - - var accept = r.Header.Get("Accept") - - var method = r.Method - - var actor = GetActorFromPath(db, path, "/") - - if actor.Name == "main" { - mainActor = (path == "/") - mainInbox = (path == "/inbox") - mainOutbox = (path == "/outbox") - mainFollowing = (path == "/following") - mainFollowers = (path == "/followers") - } else { - actorMain = (path == "/"+actor.Name) - actorInbox = (path == "/"+actor.Name+"/inbox") - actorCatalog = (path == "/"+actor.Name+"/catalog") - actorOutbox = (path == "/"+actor.Name+"/outbox") - actorFollowing = (path == "/"+actor.Name+"/following") - actorFollowers = (path == "/"+actor.Name+"/followers") - actorReported = (path == "/"+actor.Name+"/reported") - actorVerification = (path == "/"+actor.Name+"/verification") - actorArchive = (path == "/"+actor.Name+"/archive") - - escapedActorName := strings.Replace(actor.Name, "*", "\\*", -1) - escapedActorName = strings.Replace(escapedActorName, "^", "\\^", -1) - escapedActorName = strings.Replace(escapedActorName, "$", "\\$", -1) - escapedActorName = strings.Replace(escapedActorName, "?", "\\?", -1) - escapedActorName = strings.Replace(escapedActorName, "+", "\\+", -1) - escapedActorName = strings.Replace(escapedActorName, ".", "\\.", -1) - - re := regexp.MustCompile("/" + escapedActorName + "/[0-9]{1,2}$") - - actorMainPage = re.MatchString(path) - - re = regexp.MustCompile("/" + escapedActorName + "/\\w+") - - actorPost = re.MatchString(path) - } - - if mainActor { - if acceptActivity(accept) { - GetActorInfo(w, db, Domain) - return - } - - IndexGet(w, r, db) - - return - } - - if mainInbox { - if method == "POST" { - - } else { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) - } - return - } - - if mainOutbox { - if method == "GET" { - GetActorOutbox(w, r, db) - } else if method == "POST" { - ParseOutboxRequest(w, r, db) - } else { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) - } - return - } - - if mainFollowing { - GetActorFollowing(w, db, Domain) - return - } - - if mainFollowers { - GetActorFollowers(w, db, Domain) - return - } - - if actorMain || actorMainPage { - if acceptActivity(accept) { - GetActorInfo(w, db, actor.Id) - return - } - - postNum := r.URL.Query().Get("page") - - page, _ := strconv.Atoi(postNum) - collection, valid := WantToServePage(db, actor.Name, page) - - if valid { - OutboxGet(w, r, db, collection) - } - - return - } - - if actorFollowing { - GetActorFollowing(w, db, actor.Id) - return - } - - if actorFollowers { - GetActorFollowers(w, db, actor.Id) - return - } - - if actorInbox { - if method == "POST" { - ParseInboxRequest(w, r, db) - } else { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) - } - return - } - - if actorCatalog { - collection, valid := WantToServeCatalog(db, actor.Name) - if valid { - CatalogGet(w, r, db, collection) - } - return - } - - if actorOutbox { - if method == "GET" { - GetActorOutbox(w, r, db) - } else if method == "POST" { - ParseOutboxRequest(w, r, db) - } else { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) - } - return - } - - if actorArchive { - collection, valid := WantToServeArchive(db, actor.Name) - if valid { - ArchiveGet(w, r, db, collection) - } - return - } - - if actorReported { - GetActorReported(w, r, db, actor.Id) - return - } - - if actorVerification { - r.ParseForm() + /* Routing and templates */ - code := r.FormValue("code") + template := html.New("./views", ".html") - var verify Verify + TemplateFunctions(template) - verify.Board = actor.Id - verify.Identifier = "post" - - verify = GetVerificationCode(db, verify) - - auth := CreateTripCode(verify.Code) - auth = CreateTripCode(auth) - - if CreateTripCode(auth) == code { - w.WriteHeader(http.StatusOK) - } else { - w.WriteHeader(http.StatusUnauthorized) - } - - w.Write([]byte("")) - } - - //catch all - if actorPost { - if acceptActivity(accept) { - GetActorPost(w, db, path) - return - } - - PostGet(w, r, db) - return - } - - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) + app := fiber.New(fiber.Config{ + Views: template, }) - http.HandleFunc("/news/", func(w http.ResponseWriter, r *http.Request) { - timestamp := r.URL.Path[6:] + app.Static("/public", "./public") + app.Static("/static", "./views") - if len(timestamp) < 2 { - AllNewsGet(w, r, db) - return - } + /* + Main actor + */ - if timestamp[len(timestamp)-1:] == "/" { - timestamp = timestamp[:len(timestamp)-1] - } + app.Get("/", IndexGet) - ts, err := strconv.Atoi(timestamp) - if err != nil { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) - } else { - NewsGet(w, r, db, ts) - } + app.Get("/inbox", func(c *fiber.Ctx) error { + return c.SendString("main inbox") }) - http.HandleFunc("/post", func(w http.ResponseWriter, r *http.Request) { - - r.ParseMultipartForm(10 << 20) - - file, header, _ := r.FormFile("file") - - if IsPostBlacklist(db, r.FormValue("comment")) { - fmt.Println("\n\nBlacklist post blocked\n\n") - http.Redirect(w, r, Domain+"/", http.StatusMovedPermanently) - return - } - - if file != nil && header.Size > (7<<20) { - w.Write([]byte("7MB max file size")) - return - } - - if r.FormValue("inReplyTo") == "" && file == nil { - w.Write([]byte("Media is required for new posts")) - return - } - - if r.FormValue("inReplyTo") == "" || file == nil { - if r.FormValue("comment") == "" && r.FormValue("subject") == "" { - w.Write([]byte("Comment or Subject required")) - return - } - } - - if len(r.FormValue("comment")) > 2000 { - w.Write([]byte("Comment limit 2000 characters")) - return - } - - if len(r.FormValue("subject")) > 100 || len(r.FormValue("name")) > 100 || len(r.FormValue("options")) > 100 { - w.Write([]byte("Name, Subject or Options limit 100 characters")) - return - } - - if r.FormValue("captcha") == "" { - w.Write([]byte("Incorrect Captcha")) - return - } - - b := bytes.Buffer{} - we := multipart.NewWriter(&b) - - if file != nil { - var fw io.Writer - - fw, err := we.CreateFormFile("file", header.Filename) - - CheckError(err, "error with form file create") - - _, err = io.Copy(fw, file) - - CheckError(err, "error with form file copy") - } - - reply := ParseCommentForReply(r.FormValue("comment")) - - for key, r0 := range r.Form { - if key == "captcha" { - err := we.WriteField(key, r.FormValue("captchaCode")+":"+r.FormValue("captcha")) - CheckError(err, "error with writing captcha field") - } else if key == "name" { - name, tripcode := CreateNameTripCode(r, db) - err := we.WriteField(key, name) - CheckError(err, "error with writing name field") - err = we.WriteField("tripcode", tripcode) - CheckError(err, "error with writing tripcode field") - } else { - err := we.WriteField(key, r0[0]) - CheckError(err, "error with writing field") - } - } - - if r.FormValue("inReplyTo") == "" && reply != "" { - err := we.WriteField("inReplyTo", reply) - CheckError(err, "error with writing inReplyTo field") - } - - we.Close() - - sendTo := r.FormValue("sendTo") - req, err := http.NewRequest("POST", sendTo, &b) - - CheckError(err, "error with post form req") - - req.Header.Set("Content-Type", we.FormDataContentType()) - - resp, err := RouteProxy(req) - - CheckError(err, "error with post form resp") - - defer resp.Body.Close() - - if resp.StatusCode == 200 { - - body, _ := ioutil.ReadAll(resp.Body) - - var obj ObjectBase - - obj = ParseOptions(r, obj) - for _, e := range obj.Option { - if e == "noko" || e == "nokosage" { - http.Redirect(w, r, Domain+"/"+r.FormValue("boardName")+"/"+shortURL(r.FormValue("sendTo"), string(body)), http.StatusMovedPermanently) - return - } - } - - if r.FormValue("returnTo") == "catalog" { - http.Redirect(w, r, Domain+"/"+r.FormValue("boardName")+"/catalog", http.StatusMovedPermanently) - } else { - http.Redirect(w, r, Domain+"/"+r.FormValue("boardName"), http.StatusMovedPermanently) - } - return - } - - if resp.StatusCode == 403 { - w.Write([]byte("Incorrect Captcha")) - return - } - - http.Redirect(w, r, Domain+"/"+r.FormValue("boardName"), http.StatusMovedPermanently) + app.Get("/outbox", func(c *fiber.Ctx) error { + return c.SendString("main outbox") }) - http.HandleFunc("/"+*Key+"/", func(w http.ResponseWriter, r *http.Request) { - - id, _ := GetPasswordFromSession(r) - actor := GetActorFromPath(db, r.URL.Path, "/"+*Key+"/") - - if actor.Id == "" { - actor = GetActorFromDB(db, Domain) - } - - if id == "" || (id != actor.Id && id != Domain) { - t := template.Must(template.ParseFiles("./static/verify.html")) - t.Execute(w, "") - return - } - - re := regexp.MustCompile("/" + *Key + "/" + actor.Name + "/follow") - follow := re.MatchString(r.URL.Path) - - re = regexp.MustCompile("/" + *Key + "/" + actor.Name) - manage := re.MatchString(r.URL.Path) - - re = regexp.MustCompile("/" + *Key) - admin := re.MatchString(r.URL.Path) - - re = regexp.MustCompile("/" + *Key + "/follow") - adminFollow := re.MatchString(r.URL.Path) - - if follow || adminFollow { - r.ParseForm() - - following := regexp.MustCompile(`(.+)\/following`) - followers := regexp.MustCompile(`(.+)\/followers`) - - follow := r.FormValue("follow") - actorId := r.FormValue("actor") - - //follow all of boards following - if following.MatchString(follow) { - followingActor := FingerActor(follow) - col := GetActorCollection(followingActor.Following) - - var nObj ObjectBase - nObj.Id = followingActor.Id - - col.Items = append(col.Items, nObj) - - for _, e := range col.Items { - if !IsAlreadyFollowing(db, actorId, e.Id) && e.Id != Domain && e.Id != actorId { - followActivity := MakeFollowActivity(db, actorId, e.Id) - - if FingerActor(e.Id).Id != "" { - MakeActivityRequestOutbox(db, followActivity) - } - } - } - - //follow all of boards followers - } else if followers.MatchString(follow) { - followersActor := FingerActor(follow) - col := GetActorCollection(followersActor.Followers) - - var nObj ObjectBase - nObj.Id = followersActor.Id - - col.Items = append(col.Items, nObj) - - for _, e := range col.Items { - if !IsAlreadyFollowing(db, actorId, e.Id) && e.Id != Domain && e.Id != actorId { - followActivity := MakeFollowActivity(db, actorId, e.Id) - if FingerActor(e.Id).Id != "" { - MakeActivityRequestOutbox(db, followActivity) - } - } - } - - //do a normal follow to a single board - } else { - followActivity := MakeFollowActivity(db, actorId, follow) - - if followActivity.Actor.Id == Domain && !IsActorLocal(db, followActivity.Object.Actor) { - w.Write([]byte("main board can only follow local boards. Create a new board and then follow outside boards from it.")) - return - } - - if FingerActor(follow).Id != "" { - MakeActivityRequestOutbox(db, followActivity) - } - } - - var redirect string - if actor.Name != "main" { - redirect = "/" + actor.Name - } - - http.Redirect(w, r, "/"+*Key+"/"+redirect, http.StatusSeeOther) - } else if manage && actor.Name != "" { - t := template.Must(template.New("").Funcs(template.FuncMap{ - "sub": func(i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/manage.html")) - - follow := GetActorCollection(actor.Following) - follower := GetActorCollection(actor.Followers) - reported := GetActorCollectionReq(r, actor.Id+"/reported") - - var following []string - var followers []string - var reports []Report - - for _, e := range follow.Items { - following = append(following, e.Id) - } - - for _, e := range follower.Items { - followers = append(followers, e.Id) - } - - for _, e := range reported.Items { - var r Report - r.Count = int(e.Size) - r.ID = e.Id - r.Reason = e.Content - reports = append(reports, r) - } - - localReports := GetLocalReportDB(db, actor.Name) - - for _, e := range localReports { - var r Report - r.Count = e.Count - r.ID = e.ID - r.Reason = e.Reason - reports = append(reports, r) - } - - var adminData AdminPage - adminData.Following = following - adminData.Followers = followers - adminData.Reported = reports - adminData.Domain = Domain - adminData.IsLocal = IsActorLocal(db, actor.Id) - - adminData.Title = "Manage /" + actor.Name + "/" - adminData.Boards = Boards - adminData.Board.Name = actor.Name - adminData.Board.Actor = actor - adminData.Key = *Key - adminData.Board.TP = TP - - adminData.Board.Post.Actor = actor.Id - - adminData.AutoSubscribe = GetActorAutoSubscribeDB(db, actor.Id) - - adminData.Themes = &Themes - - if cookie, err := r.Cookie("theme"); err == nil { - adminData.ThemeCookie = strings.SplitN(cookie.String(), "=", 2)[1] - } - - err = t.ExecuteTemplate(w, "layout", adminData) - if err != nil { - // TODO: actual error handling - log.Printf("mod page: %s\n", err) - } - - } else if admin || actor.Id == Domain { - t := template.Must(template.New("").Funcs(template.FuncMap{ - "sub": func(i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/nadmin.html")) - - actor := GetActor(Domain) - follow := GetActorCollection(actor.Following).Items - follower := GetActorCollection(actor.Followers).Items - - var following []string - var followers []string - - for _, e := range follow { - following = append(following, e.Id) - } - - for _, e := range follower { - followers = append(followers, e.Id) - } - - var adminData AdminPage - adminData.Following = following - adminData.Followers = followers - adminData.Actor = actor.Id - adminData.Key = *Key - adminData.Domain = Domain - adminData.Board.ModCred, _ = GetPasswordFromSession(r) - - adminData.Boards = Boards - - adminData.Board.Post.Actor = actor.Id - - adminData.PostBlacklist = GetRegexBlacklistDB(db) - - adminData.Themes = &Themes - if cookie, err := r.Cookie("theme"); err == nil { - adminData.ThemeCookie = strings.SplitN(cookie.String(), "=", 2)[1] - } - - err = t.ExecuteTemplate(w, "layout", adminData) - if err != nil { - // TODO: actual error handling - log.Printf("mod page: %s\n", err) - } - } + app.Get("/following", func(c *fiber.Ctx) error { + return c.SendString("main following") }) - http.HandleFunc("/"+*Key+"/addboard", func(w http.ResponseWriter, r *http.Request) { - - actor := GetActorFromDB(db, Domain) - - if !HasValidation(w, r, actor) { - return - } - - var newActorActivity Activity - var board Actor - r.ParseForm() - - var restrict bool - if r.FormValue("restricted") == "True" { - restrict = true - } else { - restrict = false - } - - board.Name = r.FormValue("name") - board.PreferredUsername = r.FormValue("prefname") - board.Summary = r.FormValue("summary") - board.Restricted = restrict - - newActorActivity.AtContext.Context = "https://www.w3.org/ns/activitystreams" - newActorActivity.Type = "New" - - var nobj ObjectBase - newActorActivity.Actor = &actor - newActorActivity.Object = &nobj - - newActorActivity.Object.Alias = board.Name - newActorActivity.Object.Name = board.PreferredUsername - newActorActivity.Object.Summary = board.Summary - newActorActivity.Object.Sensitive = board.Restricted - - MakeActivityRequestOutbox(db, newActorActivity) - http.Redirect(w, r, "/"+*Key, http.StatusSeeOther) + app.Get("/followers", func(c *fiber.Ctx) error { + return c.SendString("main followers") }) - http.HandleFunc("/"+*Key+"/postnews", func(w http.ResponseWriter, r *http.Request) { - - actor := GetActorFromDB(db, Domain) - - if !HasValidation(w, r, actor) { - return - } + /* + Board actor + */ - var newsitem NewsItem + app.Get("/:actor", OutboxGet) - newsitem.Title = r.FormValue("title") - newsitem.Content = template.HTML(r.FormValue("summary")) + app.Get("/:actor/:post", PostGet) - WriteNewsToDB(db, newsitem) - - http.Redirect(w, r, "/", http.StatusSeeOther) + app.Get("/:actor/inbox", func(c *fiber.Ctx) error { + return c.SendString("actor inbox") }) - http.HandleFunc("/"+*Key+"/newsdelete/", func(w http.ResponseWriter, r *http.Request) { - - actor := GetActorFromDB(db, Domain) - - if !HasValidation(w, r, actor) { - return - } - - timestamp := r.URL.Path[13+len(*Key):] - - tsint, err := strconv.Atoi(timestamp) - - if err != nil { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) - return - } else { - deleteNewsItemFromDB(db, tsint) - http.Redirect(w, r, "/news/", http.StatusSeeOther) - } + app.Get("/:actor/outbox", func(c *fiber.Ctx) error { + return c.SendString("actor outbox") }) - http.HandleFunc("/verify", func(w http.ResponseWriter, r *http.Request) { - if r.Method == "POST" { - r.ParseForm() - identifier := r.FormValue("id") - code := r.FormValue("code") - - var verify Verify - verify.Identifier = identifier - verify.Code = code - - j, _ := json.Marshal(&verify) - - req, err := http.NewRequest("POST", Domain+"/auth", bytes.NewBuffer(j)) - - CheckError(err, "error making verify req") - - req.Header.Set("Content-Type", activitystreams) - - resp, err := http.DefaultClient.Do(req) - - CheckError(err, "error getting verify resp") - - defer resp.Body.Close() - - rBody, _ := ioutil.ReadAll(resp.Body) - - body := string(rBody) - - if resp.StatusCode != 200 { - t := template.Must(template.ParseFiles("./static/verify.html")) - t.Execute(w, "wrong password "+verify.Code) - } else { - - sessionToken, _ := uuid.NewV4() - - _, err := cache.Do("SETEX", sessionToken, "86400", body+"|"+verify.Code) - if err != nil { - t := template.Must(template.ParseFiles("./static/verify.html")) - t.Execute(w, "") - return - } - - http.SetCookie(w, &http.Cookie{ - Name: "session_token", - Value: sessionToken.String(), - Expires: time.Now().UTC().Add(60 * 60 * 48 * time.Second), - }) - - http.Redirect(w, r, "/", http.StatusSeeOther) - } - } else { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("404 no path")) - } + app.Get("/:actor/following", func(c *fiber.Ctx) error { + return c.SendString("actor following") }) - http.HandleFunc("/banmedia", func(w http.ResponseWriter, r *http.Request) { - id := r.URL.Query().Get("id") - board := r.URL.Query().Get("board") - - _, auth := GetPasswordFromSession(r) - - if id == "" || auth == "" { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - col := GetCollectionFromID(id) - - if len(col.OrderedItems) > 0 { - - actor := col.OrderedItems[0].Actor - - if !HasAuth(db, auth, actor) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - if len(col.OrderedItems[0].Attachment) > 0 { - re := regexp.MustCompile(Domain) - file := re.ReplaceAllString(col.OrderedItems[0].Attachment[0].Href, "") - - f, err := os.Open("." + file) - CheckError(err, "could not open attachment for ban media") - - defer f.Close() - - bytes := make([]byte, 2048) - - _, err = f.Read(bytes) - if err != nil { - fmt.Println("error readin bytes for setting media ban") - } - - if !IsMediaBanned(db, f) { - query := `insert into bannedmedia (hash) values ($1)` - - _, err := db.Exec(query, HashBytes(bytes)) - - CheckError(err, "error inserting banend media into db") - - } - - var obj ObjectBase - obj.Id = id - obj.Actor = actor - - isOP := CheckIfObjectOP(db, obj.Id) - - var OP string - if len(col.OrderedItems[0].InReplyTo) > 0 { - OP = col.OrderedItems[0].InReplyTo[0].Id - } - - if !isOP { - TombstoneObject(db, id) - } else { - TombstoneObjectAndReplies(db, id) - } - - if IsIDLocal(db, id) { - go DeleteObjectRequest(db, id) - } - - UnArchiveLast(db, actor) - - if !isOP { - if !IsIDLocal(db, id) { - http.Redirect(w, r, "/"+board+"/"+remoteShort(OP), http.StatusSeeOther) - return - } else { - http.Redirect(w, r, OP, http.StatusSeeOther) - return - } - } else { - http.Redirect(w, r, "/"+board, http.StatusSeeOther) - return - } - } - } - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) + app.Get("/:actor/followers", func(c *fiber.Ctx) error { + return c.SendString("actor followers") }) - http.HandleFunc("/delete", func(w http.ResponseWriter, r *http.Request) { - id := r.URL.Query().Get("id") - board := r.URL.Query().Get("board") - - _, auth := GetPasswordFromSession(r) - - if id == "" || auth == "" { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - manage := r.URL.Query().Get("manage") - col := GetCollectionFromID(id) - if len(col.OrderedItems) < 1 { - actor := GetActorByNameFromDB(db, board) - if !HasAuth(db, auth, actor.Id) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - if !CheckIfObjectOP(db, id) { - TombstoneObject(db, id) - } else { - TombstoneObjectAndReplies(db, id) - } - - UnArchiveLast(db, actor.Id) - - if manage == "t" { - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } else { - http.Redirect(w, r, "/"+board, http.StatusSeeOther) - return - } - } - - actor := col.OrderedItems[0].Actor - - if !HasAuth(db, auth, actor) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - var obj ObjectBase - obj.Id = id - obj.Actor = actor - - isOP := CheckIfObjectOP(db, obj.Id) - - var OP string - if len(col.OrderedItems[0].InReplyTo) > 0 { - OP = col.OrderedItems[0].InReplyTo[0].Id - } - - if !isOP { - TombstoneObject(db, id) - } else { - TombstoneObjectAndReplies(db, id) - } - - if IsIDLocal(db, id) { - go DeleteObjectRequest(db, id) - } - - UnArchiveLast(db, actor) - - if manage == "t" { - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } else if !isOP { - if !IsIDLocal(db, id) { - http.Redirect(w, r, "/"+board+"/"+remoteShort(OP), http.StatusSeeOther) - return - } else { - http.Redirect(w, r, OP, http.StatusSeeOther) - return - } - } else { - http.Redirect(w, r, "/"+board, http.StatusSeeOther) - return - } + app.Get("/:actor/reported", func(c *fiber.Ctx) error { + return c.SendString("actor reported") }) - http.HandleFunc("/deleteattach", func(w http.ResponseWriter, r *http.Request) { - - id := r.URL.Query().Get("id") - board := r.URL.Query().Get("board") - - _, auth := GetPasswordFromSession(r) - - if id == "" || auth == "" { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - manage := r.URL.Query().Get("manage") - col := GetCollectionFromID(id) - - if len(col.OrderedItems) < 1 { - if !HasAuth(db, auth, GetActorByNameFromDB(db, board).Id) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - DeleteAttachmentFromFile(db, id) - TombstoneAttachmentFromDB(db, id) - - DeletePreviewFromFile(db, id) - TombstonePreviewFromDB(db, id) - - if manage == "t" { - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } else { - http.Redirect(w, r, "/"+board, http.StatusSeeOther) - return - } - } - - actor := col.OrderedItems[0].Actor - - var OP string - if len(col.OrderedItems[0].InReplyTo) > 0 && col.OrderedItems[0].InReplyTo[0].Id != "" { - OP = col.OrderedItems[0].InReplyTo[0].Id - } else { - OP = id - } - - if !HasAuth(db, auth, actor) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - DeleteAttachmentFromFile(db, id) - TombstoneAttachmentFromDB(db, id) - - DeletePreviewFromFile(db, id) - TombstonePreviewFromDB(db, id) - - if manage == "t" { - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } else if !IsIDLocal(db, OP) { - http.Redirect(w, r, "/"+board+"/"+remoteShort(OP), http.StatusSeeOther) - return - } else { - http.Redirect(w, r, OP, http.StatusSeeOther) - return - } + app.Get("/:actor/archive", func(c *fiber.Ctx) error { + return c.SendString("actor archive") }) - http.HandleFunc("/marksensitive", func(w http.ResponseWriter, r *http.Request) { - - id := r.URL.Query().Get("id") - board := r.URL.Query().Get("board") - - _, auth := GetPasswordFromSession(r) - - if id == "" || auth == "" { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - col := GetCollectionFromID(id) - - if len(col.OrderedItems) < 1 { - if !HasAuth(db, auth, GetActorByNameFromDB(db, board).Id) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - MarkObjectSensitive(db, id, true) - - http.Redirect(w, r, "/"+board, http.StatusSeeOther) - return - } - - actor := col.OrderedItems[0].Actor - - var OP string - if len(col.OrderedItems[0].InReplyTo) > 0 && col.OrderedItems[0].InReplyTo[0].Id != "" { - OP = col.OrderedItems[0].InReplyTo[0].Id - } else { - OP = id - } - - if !HasAuth(db, auth, actor) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - MarkObjectSensitive(db, id, true) - - if !IsIDLocal(db, OP) { - http.Redirect(w, r, "/"+board+"/"+remoteShort(OP), http.StatusSeeOther) - return - } else { - http.Redirect(w, r, OP, http.StatusSeeOther) - return - } + app.Get("/post", func(c *fiber.Ctx) error { + return c.SendString("actor post") }) - http.HandleFunc("/remove", func(w http.ResponseWriter, r *http.Request) { - id := r.URL.Query().Get("id") - manage := r.URL.Query().Get("manage") - board := r.URL.Query().Get("board") - col := GetCollectionFromID(id) - actor := col.OrderedItems[0].Actor - _, auth := GetPasswordFromSession(r) - - if id == "" || auth == "" { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - if !HasAuth(db, auth, actor) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - var obj ObjectBase - obj.Id = id - obj.Actor = actor + /* + Admin routes + */ - isOP := CheckIfObjectOP(db, obj.Id) - - var OP string - if len(col.OrderedItems[0].InReplyTo) > 0 { - OP = col.OrderedItems[0].InReplyTo[0].Id - } - - if !isOP { - SetObject(db, id, "Removed") - } else { - SetObjectAndReplies(db, id, "Removed") - } - - if manage == "t" { - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } else if !isOP { - if !IsIDLocal(db, id) { - http.Redirect(w, r, "/"+board+"/"+remoteShort(OP), http.StatusSeeOther) - return - } else { - http.Redirect(w, r, OP, http.StatusSeeOther) - return - } - } else { - http.Redirect(w, r, "/"+board, http.StatusSeeOther) - return - } + app.Get("/verify", func(c *fiber.Ctx) error { + return c.SendString("admin verify") }) - http.HandleFunc("/removeattach", func(w http.ResponseWriter, r *http.Request) { - - id := r.URL.Query().Get("id") - manage := r.URL.Query().Get("manage") - board := r.URL.Query().Get("board") - col := GetCollectionFromID(id) - actor := col.OrderedItems[0].Actor - - var OP string - if len(col.OrderedItems[0].InReplyTo) > 0 && col.OrderedItems[0].InReplyTo[0].Id != "" { - OP = col.OrderedItems[0].InReplyTo[0].Id - } else { - OP = id - } - - _, auth := GetPasswordFromSession(r) - - if id == "" || auth == "" { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - if !HasAuth(db, auth, actor) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } - - SetAttachmentFromDB(db, id, "Removed") - SetPreviewFromDB(db, id, "Removed") - - if manage == "t" { - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } else if !IsIDLocal(db, OP) { - http.Redirect(w, r, "/"+board+"/"+remoteShort(OP), http.StatusSeeOther) - return - } else { - http.Redirect(w, r, OP, http.StatusSeeOther) - return - } + app.Get("/auth", func(c *fiber.Ctx) error { + return c.SendString("admin auth") }) - http.HandleFunc("/report", func(w http.ResponseWriter, r *http.Request) { - - r.ParseForm() - - id := r.FormValue("id") - board := r.FormValue("board") - reason := r.FormValue("comment") - close := r.FormValue("close") - - actor := GetActorFromPath(db, id, "/") - _, auth := GetPasswordFromSession(r) - - var captcha = r.FormValue("captchaCode") + ":" + r.FormValue("captcha") + app.Get("/"+*Key+"/", func(c *fiber.Ctx) error { + return c.SendString("admin key") + }) - if len(reason) > 100 { - w.Write([]byte("Report comment limit 100 characters")) - return - } + app.Get("/"+*Key+"/addboard", func(c *fiber.Ctx) error { + return c.SendString("admin addboard ") + }) - if close != "1" && !CheckCaptcha(db, captcha) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("captcha required")) - return - } + app.Get("/"+*Key+"/postnews", func(c *fiber.Ctx) error { + return c.SendString("admin post news") + }) - if close == "1" { - if !HasAuth(db, auth, actor.Id) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } + app.Get("/"+*Key+"/newsdelete", func(c *fiber.Ctx) error { + return c.SendString("admin news delete") + }) - if !IsIDLocal(db, id) { - CloseLocalReportDB(db, id, board) - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } + app.Get("/news", func(c *fiber.Ctx) error { + return c.SendString("admin news") + }) - reported := DeleteReportActivity(db, id) - if reported { - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) - return - } + /* + Board managment + */ - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } + app.Get("/banmedia", func(c *fiber.Ctx) error { + return c.SendString("board ban media") + }) - if !IsIDLocal(db, id) { - CreateLocalReportDB(db, id, board, reason) - http.Redirect(w, r, "/"+board+"/"+remoteShort(id), http.StatusSeeOther) - return - } + app.Get("/delete", func(c *fiber.Ctx) error { + return c.SendString("board delete") + }) - reported := ReportActivity(db, id, reason) - if reported { - http.Redirect(w, r, id, http.StatusSeeOther) - return - } + app.Get("/deleteattach", func(c *fiber.Ctx) error { + return c.SendString("board delete attach") + }) - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) + app.Get("/marksensitive", func(c *fiber.Ctx) error { + return c.SendString("board mark sensitive") }) - http.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) { - var verify Verify - defer r.Body.Close() + app.Get("/remove", func(c *fiber.Ctx) error { + return c.SendString("board remove") + }) - body, _ := ioutil.ReadAll(r.Body) + app.Get("/removeattach", func(c *fiber.Ctx) error { + return c.SendString("Hello World") + }) - err := json.Unmarshal(body, &verify) + app.Get("/addtoindex", func(c *fiber.Ctx) error { + return c.SendString("board add to index") + }) - CheckError(err, "error get verify from json") + app.Get("/poparchive", func(c *fiber.Ctx) error { + return c.SendString("board pop archive") + }) - v := GetVerificationByCode(db, verify.Code) + app.Get("/autosubscribe", func(c *fiber.Ctx) error { + return c.SendString("board autosubscribe") + }) - if v.Identifier == verify.Identifier { - w.Write([]byte(v.Board)) - return - } + app.Get("/blacklist", func(c *fiber.Ctx) error { + return c.SendString("board blacklist") + }) - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) + app.Get("/report", func(c *fiber.Ctx) error { + return c.SendString("board report") }) - http.HandleFunc("/.well-known/webfinger", func(w http.ResponseWriter, r *http.Request) { - acct := r.URL.Query()["resource"] + app.Get("/.well-known/webfinger", func(c *fiber.Ctx) error { + acct := c.Query("resource") if len(acct) < 1 { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("resource needs a value")) - return + c.Status(fiber.StatusBadRequest) + return c.Send([]byte("resource needs a value")) } - acct[0] = strings.Replace(acct[0], "acct:", "", -1) + acct = strings.Replace(acct, "acct:", "", -1) - actorDomain := strings.Split(acct[0], "@") + actorDomain := strings.Split(acct, "@") if len(actorDomain) < 2 { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("accpets only subject form of acct:board@instance")) - return + c.Status(fiber.StatusBadRequest) + return c.Send([]byte("accpets only subject form of acct:board@instance")) } if actorDomain[0] == "main" { @@ -1332,10 +288,9 @@ func main() { actorDomain[0] = "/" + actorDomain[0] } - if !IsActorLocal(db, TP+""+actorDomain[1]+""+actorDomain[0]) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("actor not local")) - return + if !IsActorLocal(DB, TP+""+actorDomain[1]+""+actorDomain[0]) { + c.Status(fiber.StatusBadRequest) + return c.Send([]byte("actor not local")) } var finger Webfinger @@ -1350,107 +305,20 @@ func main() { enc, _ := json.Marshal(finger) - w.Header().Set("Content-Type", activitystreams) - w.Write(enc) - + c.Set("Content-Type", activitystreams) + return c.Send(enc) }) - http.HandleFunc("/addtoindex", func(w http.ResponseWriter, r *http.Request) { - actor := r.URL.Query().Get("id") - - if Domain != "https://fchan.xyz" { - return - } - - go AddInstanceToIndexDB(db, actor) - }) - - http.HandleFunc("/poparchive", func(w http.ResponseWriter, r *http.Request) { - - actor := GetActorFromDB(db, Domain) - - if !HasValidation(w, r, actor) { - return - } - - id := r.URL.Query().Get("id") - board := r.URL.Query().Get("board") - - SetObjectType(db, id, "Note") - - http.Redirect(w, r, "/"+board+"/archive", http.StatusSeeOther) - }) - - http.HandleFunc("/blacklist", func(w http.ResponseWriter, r *http.Request) { - - actor := GetActorFromDB(db, Domain) - - if !HasValidation(w, r, actor) { - return - } - - if r.Method == "GET" { - id := r.URL.Query().Get("remove") - - if id != "" { - i, _ := strconv.Atoi(id) - DeleteRegexBlacklistDB(db, i) - } - - } else { - regex := r.FormValue("regex") - testCase := r.FormValue("testCase") - - if regex == "" { - http.Redirect(w, r, "/", http.StatusSeeOther) - return - } - - r.ParseForm() - - re := regexp.MustCompile(regex) - - if testCase == "" { - WriteRegexBlacklistDB(db, regex) - } else if re.MatchString(testCase) { - WriteRegexBlacklistDB(db, regex) - } - } - - http.Redirect(w, r, "/"+*Key+"#regex", http.StatusSeeOther) - }) - - http.HandleFunc("/api/media", func(w http.ResponseWriter, r *http.Request) { - if r.URL.Query().Get("hash") != "" { - RouteImages(w, r.URL.Query().Get("hash")) - } - }) - - http.HandleFunc("/autosubscribe", func(w http.ResponseWriter, r *http.Request) { - - if !HasValidation(w, r, GetActorFromDB(db, Domain)) { - return - } - - board := r.URL.Query().Get("board") - actor := GetActorByNameFromDB(db, board) - - SetActorAutoSubscribeDB(db, actor.Id) - autoSub := GetActorAutoSubscribeDB(db, actor.Id) - - if autoSub { - AutoFollow(db, actor.Id) - } - - http.Redirect(w, r, "/"+*Key+"/"+board, http.StatusSeeOther) + app.Get("/api/media", func(c *fiber.Ctx) error { + return c.SendString("api media") }) fmt.Println("Server for " + Domain + " running on port " + Port) fmt.Println("Mod key: " + *Key) - PrintAdminAuth(db) + PrintAdminAuth(DB) - http.ListenAndServe(Port, nil) + app.Listen(Port) } func CheckError(e error, m string) error { @@ -3002,3 +1870,68 @@ func CheckInactiveInstances(db *sql.DB) map[string]string { return instances } + +func TemplateFunctions(engine *html.Engine) { + engine.AddFunc( + "mod", mod, + ) + + engine.AddFunc( + "sub", sub, + ) + + engine.AddFunc( + "unixtoreadable", unixToReadable, + ) + + engine.AddFunc("proxy", func(url string) string { + return MediaProxy(url) + }) + + engine.AddFunc("short", func(actorName string, url string) string { + return shortURL(actorName, url) + }) + + engine.AddFunc("parseAttachment", func(obj ObjectBase, catalog bool) template.HTML { + return ParseAttachment(obj, catalog) + }) + + engine.AddFunc("parseContent", func(board Actor, op string, content string, thread ObjectBase) template.HTML { + return ParseContent(DB, board, op, content, thread) + }) + + engine.AddFunc("shortImg", func(url string) string { + return ShortImg(url) + }) + + engine.AddFunc("convertSize", func(size int64) string { + return ConvertSize(size) + }) + + engine.AddFunc("isOnion", func(url string) bool { + return IsOnion(url) + }) + + engine.AddFunc("parseReplyLink", func(actorId string, op string, id string, content string) template.HTML { + actor := FingerActor(actorId) + title := strings.ReplaceAll(ParseLinkTitle(actor.Id, op, content), `/\<`, ">") + link := "<a href=\"" + actor.Name + "/" + shortURL(actor.Outbox, op) + "#" + shortURL(actor.Outbox, id) + "\" title=\"" + title + "\" class=\"replyLink\">>>" + shortURL(actor.Outbox, id) + "</a>" + return template.HTML(link) + }) + + engine.AddFunc("add", func(i, j int) int { + return i + j + }) + + engine.AddFunc( + "timeToReadableLong", timeToReadableLong, + ) + + engine.AddFunc( + "timeToUnix", timeToUnix, + ) + + engine.AddFunc( + "sub", sub, + ) +} |