aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go527
1 files changed, 44 insertions, 483 deletions
diff --git a/main.go b/main.go
index bafa0ee..363a88f 100644
--- a/main.go
+++ b/main.go
@@ -1,8 +1,14 @@
package main
import (
- "encoding/json"
"fmt"
+ "html/template"
+ "io/ioutil"
+ "math/rand"
+ "path"
+ "regexp"
+ "strings"
+ "time"
"github.com/FChannel0/FChannel-Server/activitypub"
"github.com/FChannel0/FChannel-Server/config"
@@ -15,91 +21,17 @@ import (
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/template/html"
- // "github.com/gofrs/uuid"
_ "github.com/lib/pq"
-
- "html/template"
- // "io"
- "io/ioutil"
- // "log"
- "math/rand"
- "net/http"
- "os"
- "os/exec"
- "path"
- "regexp"
- "strings"
- "time"
)
-var MediaHashs = make(map[string]string)
-
-var Themes []string
-
-func init() {
- rand.Seed(time.Now().UnixNano())
-}
-
func main() {
- var err error
- CreatedNeededDirectories()
+ Init()
- db.ConnectDB()
defer db.Close()
-
- db.InitCache()
defer db.CloseCache()
- db.RunDatabaseSchema()
-
- go MakeCaptchas(100)
-
- config.Key = util.CreateKey(32)
-
- webfinger.FollowingBoards, err = activitypub.GetActorFollowingDB(config.Domain)
-
- if err != nil {
- panic(err)
- }
-
- go db.StartupArchive()
-
- go db.CheckInactive()
-
- webfinger.Boards, err = webfinger.GetBoardCollection()
-
- if err != nil {
- panic(err)
- }
-
- // root actor is used to follow remote feeds that are not local
- //name, prefname, summary, auth requirements, restricted
- if config.InstanceName != "" {
- if _, err = db.CreateNewBoardDB(*activitypub.CreateNewActor("", config.InstanceName, config.InstanceSummary, config.AuthReq, false)); err != nil {
- //panic(err)
- }
-
- if config.PublicIndexing == "true" {
- // TODO: comment out later
- //AddInstanceToIndex(config.Domain)
- }
- }
-
- // get list of themes
- themes, err := ioutil.ReadDir("./static/css/themes")
- if err != nil {
- panic(err)
- }
-
- for _, f := range themes {
- if e := path.Ext(f.Name()); e == ".css" {
- config.Themes = append(config.Themes, strings.TrimSuffix(f.Name(), e))
- }
- }
-
- /* Routing and templates */
-
+ // Routing and templates
template := html.New("./views", ".html")
template.Debug(true)
@@ -116,485 +48,114 @@ func main() {
app.Static("/static", "./static")
app.Static("/public", "./public")
- /*
- Main actor
- */
-
+ // Main actor
app.Get("/", routes.Index)
-
app.Get("/inbox", routes.Inbox)
app.Get("/outbox", routes.Outbox)
-
app.Get("/following", routes.Following)
app.Get("/followers", routes.Followers)
- /*
- Admin routes
- */
-
+ // Admin routes
app.Get("/verify", routes.AdminVerify)
-
app.Get("/auth", routes.AdminAuth)
-
app.Get("/"+config.Key+"/", routes.AdminIndex)
-
app.Get("/"+config.Key+"/addboard", routes.AdminAddBoard)
-
app.Get("/"+config.Key+"/postnews", routes.AdminPostNews)
app.Get("/"+config.Key+"/newsdelete", routes.AdminNewsDelete)
app.Get("/news", routes.NewsGet)
- /*
- Board managment
- */
-
+ // Board managment
app.Get("/banmedia", routes.BoardBanMedia)
app.Get("/delete", routes.BoardDelete)
-
app.Get("/deleteattach", routes.BoardDeleteAttach)
app.Get("/marksensitive", routes.BoardMarkSensitive)
-
app.Get("/remove", routes.BoardRemove)
app.Get("/removeattach", routes.BoardRemoveAttach)
-
app.Get("/addtoindex", routes.BoardAddToIndex)
-
app.Get("/poparchive", routes.BoardPopArchive)
-
app.Get("/autosubscribe", routes.BoardAutoSubscribe)
-
app.Get("/blacklist", routes.BoardBlacklist)
app.Get("/report", routes.BoardBlacklist)
+ app.Get("/.well-known/webfinger", routes.Webfinger)
+ app.Get("/api/media", routes.Media)
- app.Get("/.well-known/webfinger", func(c *fiber.Ctx) error {
- acct := c.Query("resource")
-
- if len(acct) < 1 {
- c.Status(fiber.StatusBadRequest)
- return c.Send([]byte("resource needs a value"))
- }
-
- acct = strings.Replace(acct, "acct:", "", -1)
-
- actorDomain := strings.Split(acct, "@")
-
- if len(actorDomain) < 2 {
- c.Status(fiber.StatusBadRequest)
- return c.Send([]byte("accpets only subject form of acct:board@instance"))
- }
-
- if actorDomain[0] == "main" {
- actorDomain[0] = ""
- } else {
- actorDomain[0] = "/" + actorDomain[0]
- }
-
- if res, err := activitypub.IsActorLocal(config.TP + "" + actorDomain[1] + "" + actorDomain[0]); err == nil && !res {
- c.Status(fiber.StatusBadRequest)
- return c.Send([]byte("actor not local"))
- } else if err != nil {
- return err
- }
-
- var finger webfinger.Webfinger
- var link webfinger.WebfingerLink
-
- finger.Subject = "acct:" + actorDomain[0] + "@" + actorDomain[1]
- link.Rel = "self"
- link.Type = "application/activity+json"
- link.Href = config.TP + "" + actorDomain[1] + "" + actorDomain[0]
-
- finger.Links = append(finger.Links, link)
-
- enc, _ := json.Marshal(finger)
-
- c.Set("Content-Type", config.ActivityStreams)
- return c.Send(enc)
- })
-
- app.Get("/api/media", func(c *fiber.Ctx) error {
- if c.Query("hash") != "" {
- return RouteImages(c, c.Query("hash"))
- }
-
- return c.SendStatus(404)
- })
-
- /*
- Board actor
- */
-
+ // Board actor
app.Get("/:actor", routes.OutboxGet)
app.Post("/:actor", routes.ActorPost)
-
app.Get("/:actor/catalog", routes.CatalogGet)
app.Get("/:actor/:post", routes.PostGet)
-
app.Get("/:actor/inbox", routes.ActorInbox)
app.Post("/:actor/outbox", routes.ActorOutbox)
-
app.Get("/:actor/following", routes.ActorFollowing)
app.Get("/:actor/followers", routes.ActorFollowers)
-
app.Get("/:actor/reported", routes.ActorReported)
app.Get("/:actor/archive", routes.ActorArchive)
//404 handler
app.Use(routes.NotFound)
- fmt.Println("Mod key: " + config.Key)
- PrintAdminAuth()
+ db.PrintAdminAuth()
app.Listen(config.Port)
}
-func neuter(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if strings.HasSuffix(r.URL.Path, "/") {
- http.NotFound(w, r)
- return
- }
-
- next.ServeHTTP(w, r)
- })
-}
-
-func IsValidActor(id string) (activitypub.Actor, bool, error) {
- actor, err := webfinger.FingerActor(id)
- return actor, actor.Id != "", err
-}
-
-func MakeCaptchas(total int) error {
- dbtotal, err := db.GetCaptchaTotal()
- if err != nil {
- return err
- }
-
- difference := total - dbtotal
-
- for i := 0; i < difference; i++ {
- if err := db.CreateNewCaptcha(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func GetActorReported(w http.ResponseWriter, r *http.Request, id string) error {
- auth := r.Header.Get("Authorization")
- verification := strings.Split(auth, " ")
-
- if len(verification) < 2 {
- w.WriteHeader(http.StatusBadRequest)
- _, err := w.Write([]byte(""))
- return err
- }
-
- if res, err := db.HasAuth(verification[1], id); err == nil && !res {
- w.WriteHeader(http.StatusBadRequest)
- _, err = w.Write([]byte(""))
- return err
- } else if err != nil {
- return err
- }
-
- var following activitypub.Collection
+func Init() {
var err error
- following.AtContext.Context = "https://www.w3.org/ns/activitystreams"
- following.Type = "Collection"
- following.TotalItems, err = activitypub.GetActorReportedTotal(id)
- if err != nil {
- return err
- }
-
- following.Items, err = activitypub.GetActorReportedDB(id)
- if err != nil {
- return err
- }
-
- enc, err := json.MarshalIndent(following, "", "\t")
- if err != nil {
- return err
- }
-
- w.Header().Set("Content-Type", config.ActivityStreams)
-
- _, err = w.Write(enc)
- return err
-}
-
-func PrintAdminAuth() error {
- identifier, code, err := db.GetAdminAuth()
- if err != nil {
- return err
- }
-
- fmt.Println("Admin Login: " + identifier + ", Code: " + code)
- return nil
-}
-
-func DeleteObjectRequest(id string) error {
- var nObj activitypub.ObjectBase
- var nActor activitypub.Actor
- nObj.Id = id
- nObj.Actor = nActor.Id
-
- activity, err := webfinger.CreateActivity("Delete", nObj)
- if err != nil {
- return err
- }
-
- obj, err := activitypub.GetObjectFromPath(id)
- if err != nil {
- return err
- }
-
- actor, err := webfinger.FingerActor(obj.Actor)
- if err != nil {
- return err
- }
- activity.Actor = &actor
-
- followers, err := activitypub.GetActorFollowDB(obj.Actor)
- if err != nil {
- return err
- }
-
- for _, e := range followers {
- activity.To = append(activity.To, e.Id)
- }
-
- following, err := activitypub.GetActorFollowingDB(obj.Actor)
- if err != nil {
- return err
- }
- for _, e := range following {
- activity.To = append(activity.To, e.Id)
- }
+ rand.Seed(time.Now().UnixNano())
- return db.MakeActivityRequest(activity)
-}
+ util.CreatedNeededDirectories()
-func DeleteObjectAndRepliesRequest(id string) error {
- var nObj activitypub.ObjectBase
- var nActor activitypub.Actor
- nObj.Id = id
- nObj.Actor = nActor.Id
+ db.ConnectDB()
- activity, err := webfinger.CreateActivity("Delete", nObj)
- if err != nil {
- return err
- }
+ db.InitCache()
- obj, err := activitypub.GetObjectByIDFromDB(id)
- if err != nil {
- return err
- }
+ db.RunDatabaseSchema()
- activity.Actor.Id = obj.OrderedItems[0].Actor
+ go db.MakeCaptchas(100)
- activity.Object = &obj.OrderedItems[0]
+ config.Key = util.CreateKey(32)
- followers, err := activitypub.GetActorFollowDB(obj.OrderedItems[0].Actor)
- if err != nil {
- return err
- }
- for _, e := range followers {
- activity.To = append(activity.To, e.Id)
- }
+ webfinger.FollowingBoards, err = activitypub.GetActorFollowingDB(config.Domain)
- following, err := activitypub.GetActorFollowingDB(obj.OrderedItems[0].Actor)
if err != nil {
- return err
- }
-
- for _, e := range following {
- activity.To = append(activity.To, e.Id)
- }
-
- return db.MakeActivityRequest(activity)
-}
-
-func ResizeAttachmentToPreview() error {
- return activitypub.GetObjectsWithoutPreviewsCallback(func(id, href, mediatype, name string, size int, published time.Time) error {
- re := regexp.MustCompile(`^\w+`)
-
- _type := re.FindString(mediatype)
-
- if _type == "image" {
-
- re = regexp.MustCompile(`.+/`)
-
- file := re.ReplaceAllString(mediatype, "")
-
- nHref := util.GetUniqueFilename(file)
-
- var nPreview activitypub.NestedObjectBase
-
- re = regexp.MustCompile(`/\w+$`)
- actor := re.ReplaceAllString(id, "")
-
- nPreview.Type = "Preview"
- uid, err := util.CreateUniqueID(actor)
- if err != nil {
- return err
- }
-
- nPreview.Id = fmt.Sprintf("%s/%s", actor, uid)
- nPreview.Name = name
- nPreview.Href = config.Domain + "" + nHref
- nPreview.MediaType = mediatype
- nPreview.Size = int64(size)
- nPreview.Published = published
- nPreview.Updated = published
-
- re = regexp.MustCompile(`/public/.+`)
-
- objFile := re.FindString(href)
-
- if id != "" {
- cmd := exec.Command("convert", "."+objFile, "-resize", "250x250>", "-strip", "."+nHref)
-
- if err := cmd.Run(); err == nil {
- fmt.Println(objFile + " -> " + nHref)
- if err := activitypub.WritePreviewToDB(nPreview); err != nil {
- return err
- }
- if err := activitypub.UpdateObjectWithPreview(id, nPreview.Id); err != nil {
- return err
- }
- } else {
- return err
- }
- }
- }
-
- return nil
- })
-}
-
-func CreatedNeededDirectories() {
- if _, err := os.Stat("./public"); os.IsNotExist(err) {
- os.Mkdir("./public", 0755)
+ panic(err)
}
- if _, err := os.Stat("./pem/board"); os.IsNotExist(err) {
- os.MkdirAll("./pem/board", 0700)
- }
-}
+ go db.StartupArchive()
-func AddInstanceToIndex(actor string) error {
- // TODO: completely disabling this until it is actually reasonable to turn it on
- // only actually allow this when it more or less works, i.e. can post, make threads, manage boards, etc
- return nil
+ go db.CheckInactive()
- // if local testing enviroment do not add to index
- re := regexp.MustCompile(`(.+)?(localhost|\d+\.\d+\.\d+\.\d+)(.+)?`)
- if re.MatchString(actor) {
- return nil
- }
+ webfinger.Boards, err = webfinger.GetBoardCollection()
- // also while i'm here
- // TODO: maybe allow different indexes?
- followers, err := activitypub.GetCollectionFromID("https://fchan.xyz/followers")
if err != nil {
- return err
- }
-
- var alreadyIndex = false
- for _, e := range followers.Items {
- if e.Id == actor {
- alreadyIndex = true
- }
+ panic(err)
}
- if !alreadyIndex {
- req, err := http.NewRequest("GET", "https://fchan.xyz/addtoindex?id="+actor, nil)
- if err != nil {
- return err
- }
-
- if _, err := http.DefaultClient.Do(req); err != nil {
- return err
+ // root actor is used to follow remote feeds that are not local
+ //name, prefname, summary, auth requirements, restricted
+ if config.InstanceName != "" {
+ if _, err = db.CreateNewBoardDB(*activitypub.CreateNewActor("", config.InstanceName, config.InstanceSummary, config.AuthReq, false)); err != nil {
+ //panic(err)
}
- }
-
- return nil
-}
-
-func AddInstanceToIndexDB(actor string) error {
- // TODO: completely disabling this until it is actually reasonable to turn it on
- // only actually allow this when it more or less works, i.e. can post, make threads, manage boards, etc
- return nil
- //sleep to be sure the webserver is fully initialized
- //before making finger request
- time.Sleep(15 * time.Second)
-
- nActor, err := webfinger.FingerActor(actor)
- if err != nil {
- return err
- }
-
- if nActor.Id == "" {
- return nil
- }
-
- // TODO: maybe allow different indexes?
- followers, err := activitypub.GetCollectionFromID("https://fchan.xyz/followers")
- if err != nil {
- return err
- }
-
- var alreadyIndex = false
- for _, e := range followers.Items {
- if e.Id == nActor.Id {
- alreadyIndex = true
+ if config.PublicIndexing == "true" {
+ // TODO: comment out later
+ //AddInstanceToIndex(config.Domain)
}
}
- if !alreadyIndex {
- return activitypub.AddFollower("https://fchan.xyz", nActor.Id)
- }
-
- return nil
-}
-
-func RouteImages(ctx *fiber.Ctx, media string) error {
- req, err := http.NewRequest("GET", MediaHashs[media], nil)
- if err != nil {
- return err
- }
-
- client := http.Client{
- Timeout: 5 * time.Second,
- }
-
- resp, err := client.Do(req)
+ // get list of themes
+ themes, err := ioutil.ReadDir("./static/css/themes")
if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- fileBytes, err := ioutil.ReadFile("./static/notfound.png")
- if err != nil {
- return err
- }
-
- return ctx.Send(fileBytes)
+ panic(err)
}
- body, _ := ioutil.ReadAll(resp.Body)
- for name, values := range resp.Header {
- for _, value := range values {
- ctx.Append(name, value)
+ for _, f := range themes {
+ if e := path.Ext(f.Name()); e == ".css" {
+ config.Themes = append(config.Themes, strings.TrimSuffix(f.Name(), e))
}
}
-
- return ctx.Send(body)
}
func TemplateFunctions(engine *html.Engine) {