aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--activitypub/actor.go12
-rw-r--r--activitypub/object.go33
-rw-r--r--main.go11
-rw-r--r--routes/actor.go12
-rw-r--r--routes/admin.go142
-rw-r--r--routes/follow.go17
-rw-r--r--routes/structs.go1
-rw-r--r--views/manage.html (renamed from static/manage.html)57
-rw-r--r--webfinger/comm.go1
9 files changed, 225 insertions, 61 deletions
diff --git a/activitypub/actor.go b/activitypub/actor.go
index 3fbcb75..757f6bf 100644
--- a/activitypub/actor.go
+++ b/activitypub/actor.go
@@ -339,7 +339,7 @@ func GetActorFollowTotal(id string) (int, int, error) {
return following, followers, nil
}
-func GetActorFollowers(w http.ResponseWriter, id string) error {
+func GetActorFollowers(ctx *fiber.Ctx, id string) error {
var following Collection
var err error
@@ -356,12 +356,12 @@ func GetActorFollowers(w http.ResponseWriter, id string) error {
}
enc, _ := json.MarshalIndent(following, "", "\t")
- w.Header().Set("Content-Type", config.ActivityStreams)
- _, err = w.Write(enc)
+ ctx.Response().Header.Set("Content-Type", config.ActivityStreams)
+ _, err = ctx.Write(enc)
return err
}
-func GetActorFollowing(w http.ResponseWriter, id string) error {
+func GetActorFollowing(ctx *fiber.Ctx, id string) error {
var following Collection
var err error
@@ -378,8 +378,8 @@ func GetActorFollowing(w http.ResponseWriter, id string) error {
}
enc, _ := json.MarshalIndent(following, "", "\t")
- w.Header().Set("Content-Type", config.ActivityStreams)
- _, err = w.Write(enc)
+ ctx.Response().Header.Set("Content-Type", config.ActivityStreams)
+ _, err = ctx.Write(enc)
return err
}
diff --git a/activitypub/object.go b/activitypub/object.go
index 1256fac..c461310 100644
--- a/activitypub/object.go
+++ b/activitypub/object.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
+ "log"
"mime/multipart"
"net/http"
"os"
@@ -1777,3 +1778,35 @@ func WriteWalletToDB(obj ObjectBase) error {
}
return nil
}
+
+func GetRecentPostsDB(actorID string) []ObjectBase {
+ var collection []ObjectBase
+
+ query := `select id, actor, content, published, attachment from activitystream where actor=$1 and type='Note' union select id, actor, content, published, attachment from cacheactivitystream where actor in (select follower from follower where id=$1) and type='Note' order by published desc limit 20`
+
+ rows, err := config.DB.Query(query, actorID)
+
+ if err != nil {
+ log.Println("Could not get recent posts")
+ }
+
+ defer rows.Close()
+ for rows.Next() {
+ var nObj ObjectBase
+ var attachmentID string
+ rows.Scan(&nObj.Id, &nObj.Actor, &nObj.Content, &nObj.Published, &attachmentID)
+
+ isOP, _ := CheckIfObjectOP(nObj.Id)
+ nObj.Attachment, _ = GetObjectAttachment(attachmentID)
+
+ if !isOP {
+ var reply ObjectBase
+ reply.Id = nObj.Id
+ nObj.InReplyTo = append(nObj.InReplyTo, reply)
+ }
+
+ collection = append(collection, nObj)
+ }
+
+ return collection
+}
diff --git a/main.go b/main.go
index ec1e61f..5410cf1 100644
--- a/main.go
+++ b/main.go
@@ -59,9 +59,12 @@ func main() {
app.Post("/verify", routes.AdminVerify)
app.Post("/auth", routes.AdminAuth)
app.All("/"+config.Key+"/", routes.AdminIndex)
+ app.Post("/"+config.Key+"/follow", routes.AdminFollow)
app.Get("/"+config.Key+"/addboard", routes.AdminAddBoard)
app.Get("/"+config.Key+"/postnews", routes.AdminPostNews)
app.Get("/"+config.Key+"/newsdelete", routes.AdminNewsDelete)
+ app.Post("/"+config.Key+"/:actor/follow", routes.AdminActorIndex)
+ app.Get("/"+config.Key+"/:actor", routes.AdminActorIndex)
app.Get("/news", routes.NewsGet)
// Board managment
@@ -80,16 +83,16 @@ func main() {
app.Get("/api/media", routes.Media)
// 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.Post("/:actor/inbox", routes.ActorInbox)
app.Post("/:actor/outbox", routes.ActorOutbox)
app.Get("/:actor/following", routes.ActorFollowing)
- app.Get("/:actor/followers", routes.ActorFollowers)
+ app.All("/:actor/followers", routes.ActorFollowers)
app.Get("/:actor/reported", routes.ActorReported)
app.Get("/:actor/archive", routes.ActorArchive)
+ app.Get("/:actor", routes.OutboxGet)
+ app.Post("/:actor", routes.ActorPost)
+ app.Get("/:actor/:post", routes.PostGet)
//404 handler
app.Use(routes.NotFound)
diff --git a/routes/actor.go b/routes/actor.go
index d8b6631..d564850 100644
--- a/routes/actor.go
+++ b/routes/actor.go
@@ -403,16 +403,12 @@ func ActorOutbox(ctx *fiber.Ctx) error {
return nil
}
-func ActorFollowing(c *fiber.Ctx) error {
- // STUB
-
- return c.SendString("actor following")
+func ActorFollowing(ctx *fiber.Ctx) error {
+ return activitypub.GetActorFollowing(ctx, config.Domain+"/"+ctx.Params("actor"))
}
-func ActorFollowers(c *fiber.Ctx) error {
- // STUB
-
- return c.SendString("actor followers")
+func ActorFollowers(ctx *fiber.Ctx) error {
+ return activitypub.GetActorFollowers(ctx, config.Domain+"/"+ctx.Params("actor"))
}
func ActorReported(c *fiber.Ctx) error {
diff --git a/routes/admin.go b/routes/admin.go
index a6978f4..e80d24f 100644
--- a/routes/admin.go
+++ b/routes/admin.go
@@ -3,10 +3,10 @@ package routes
import (
"bytes"
"encoding/json"
- "fmt"
"io/ioutil"
"log"
"net/http"
+ "regexp"
"time"
"github.com/FChannel0/FChannel-Server/activitypub"
@@ -96,7 +96,6 @@ func AdminAuth(ctx *fiber.Ctx) error {
}
func AdminIndex(ctx *fiber.Ctx) error {
- fmt.Println("admin index")
id, _ := db.GetPasswordFromSession(ctx)
actor, _ := webfinger.GetActorFromPath(ctx.Path(), "/"+config.Key+"/")
@@ -150,6 +149,77 @@ func AdminIndex(ctx *fiber.Ctx) error {
})
}
+func AdminFollow(ctx *fiber.Ctx) error {
+ actor, _ := webfinger.GetActorFromPath(ctx.Path(), "/"+config.Key+"/")
+
+ following := regexp.MustCompile(`(.+)\/following`)
+ followers := regexp.MustCompile(`(.+)\/followers`)
+
+ follow := ctx.FormValue("follow")
+ actorId := ctx.FormValue("actor")
+
+ //follow all of boards following
+ if following.MatchString(follow) {
+ followingActor, _ := webfinger.FingerActor(follow)
+ col, _ := webfinger.GetActorCollection(followingActor.Following)
+
+ var nObj activitypub.ObjectBase
+ nObj.Id = followingActor.Id
+
+ col.Items = append(col.Items, nObj)
+
+ for _, e := range col.Items {
+ if isFollowing, _ := activitypub.IsAlreadyFollowing(actorId, e.Id); isFollowing && e.Id != config.Domain && e.Id != actorId {
+ followActivity, _ := db.MakeFollowActivity(actorId, e.Id)
+
+ if actor, _ := webfinger.FingerActor(e.Id); actor.Id != "" {
+ db.MakeActivityRequestOutbox(followActivity)
+ }
+ }
+ }
+
+ //follow all of boards followers
+ } else if followers.MatchString(follow) {
+ followersActor, _ := webfinger.FingerActor(follow)
+ col, _ := webfinger.GetActorCollection(followersActor.Followers)
+
+ var nObj activitypub.ObjectBase
+ nObj.Id = followersActor.Id
+
+ col.Items = append(col.Items, nObj)
+
+ for _, e := range col.Items {
+ if isFollowing, _ := activitypub.IsAlreadyFollowing(actorId, e.Id); isFollowing && e.Id != config.Domain && e.Id != actorId {
+ followActivity, _ := db.MakeFollowActivity(actorId, e.Id)
+ if actor, _ := webfinger.FingerActor(e.Id); actor.Id != "" {
+ db.MakeActivityRequestOutbox(followActivity)
+ }
+ }
+ }
+
+ //do a normal follow to a single board
+ } else {
+ followActivity, _ := db.MakeFollowActivity(actorId, follow)
+
+ if isLocal, _ := activitypub.IsActorLocal(followActivity.Object.Actor); !isLocal && followActivity.Actor.Id == config.Domain {
+ _, err := ctx.Write([]byte("main board can only follow local boards. Create a new board and then follow outside boards from it."))
+ return err
+ }
+
+ if actor, _ := webfinger.FingerActor(follow); actor.Id != "" {
+ db.MakeActivityRequestOutbox(followActivity)
+ }
+ }
+
+ var redirect string
+
+ if actor.Name != "main" {
+ redirect = "/" + actor.Name
+ }
+
+ return ctx.Redirect("/"+config.Key+"/"+redirect, http.StatusSeeOther)
+}
+
func AdminAddBoard(c *fiber.Ctx) error {
// STUB
@@ -167,3 +237,71 @@ func AdminNewsDelete(c *fiber.Ctx) error {
return c.SendString("admin news delete")
}
+
+func AdminActorIndex(ctx *fiber.Ctx) error {
+ actor, _ := webfinger.GetActorFromPath(ctx.Path(), "/"+config.Key+"/")
+
+ follow, _ := webfinger.GetActorCollection(actor.Following)
+ follower, _ := webfinger.GetActorCollection(actor.Followers)
+ reported, _ := activitypub.GetActorCollectionReq(actor.Id + "/reported")
+
+ var following []string
+ var followers []string
+ var reports []db.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 db.Report
+ r.Count = int(e.Size)
+ r.ID = e.Id
+ r.Reason = e.Content
+ reports = append(reports, r)
+ }
+
+ localReports, _ := db.GetLocalReportDB(actor.Name)
+
+ for _, e := range localReports {
+ var r db.Report
+ r.Count = e.Count
+ r.ID = e.ID
+ r.Reason = e.Reason
+ reports = append(reports, r)
+ }
+
+ var data AdminPage
+ data.Following = following
+ data.Followers = followers
+ data.Reported = reports
+ data.Domain = config.Domain
+ data.IsLocal, _ = activitypub.IsActorLocal(actor.Id)
+
+ data.Title = "Manage /" + actor.Name + "/"
+ data.Boards = webfinger.Boards
+ data.Board.Name = actor.Name
+ data.Board.Actor = actor
+ data.Key = config.Key
+ data.Board.TP = config.TP
+
+ data.Board.Post.Actor = actor.Id
+
+ data.AutoSubscribe, _ = activitypub.GetActorAutoSubscribeDB(actor.Id)
+
+ data.Themes = &config.Themes
+
+ data.RecentPosts = activitypub.GetRecentPostsDB(actor.Id)
+
+ if cookie := ctx.Cookies("theme"); cookie != "" {
+ data.ThemeCookie = cookie
+ }
+
+ return ctx.Render("manage", fiber.Map{
+ "page": data,
+ })
+}
diff --git a/routes/follow.go b/routes/follow.go
index 2578983..3dbf9cf 100644
--- a/routes/follow.go
+++ b/routes/follow.go
@@ -1,15 +1,16 @@
package routes
-import "github.com/gofiber/fiber/v2"
+import (
+ "github.com/FChannel0/FChannel-Server/activitypub"
+ "github.com/FChannel0/FChannel-Server/config"
+ "github.com/gofiber/fiber/v2"
+)
-func Following(c *fiber.Ctx) error {
- // STUB
-
- return c.SendString("main following")
+func Following(ctx *fiber.Ctx) error {
+ return activitypub.GetActorFollowing(ctx, config.Domain)
}
-func Followers(c *fiber.Ctx) error {
+func Followers(ctx *fiber.Ctx) error {
// STUB
-
- return c.SendString("main followers")
+ return activitypub.GetActorFollowers(ctx, config.Domain)
}
diff --git a/routes/structs.go b/routes/structs.go
index 7c6e980..1c85676 100644
--- a/routes/structs.go
+++ b/routes/structs.go
@@ -42,6 +42,7 @@ type AdminPage struct {
IsLocal bool
PostBlacklist []util.PostBlacklist
AutoSubscribe bool
+ RecentPosts []activitypub.ObjectBase
Themes *[]string
ThemeCookie string
diff --git a/static/manage.html b/views/manage.html
index c3d818c..af887e3 100644
--- a/static/manage.html
+++ b/views/manage.html
@@ -1,36 +1,30 @@
-{{ define "title" }}{{ .Title }}{{ end }}
-{{ define "header" }}
-<script src="/static/js/posts.js"></script>
-{{ end }}
-{{ define "top" }}{{ end }}
-{{ define "content" }}
<div style="text-align: center; margin: 0 auto; width: 400px;">
- <h1>Manage /{{ .Board.Name }}/</h1>
+ <h1>Manage /{{ .page.Board.Name }}/</h1>
<!-- <div><a href="/{{ .Key }}/deleteboard?name={{ .Board.Name }}">[Delete Board]</a></div> -->
<ul style="display: inline-block; padding: 0;">
- {{ if .IsLocal }}
+ {{ if .page.IsLocal }}
<li style="display: inline-block;">[<a href="#following"> Subscribed </a>]</li>
<li style="display: inline-block;">[<a href="#followers"> Subscribers </a>]</li>
{{ end }}
- <li style="display: inline-block;">[<a href="#reported"> Reported </a>]</li>
+ <li style="display: inline-block;">[<a href="#reported"> Reported </a>]</li>
</ul>
-</div>
-[<a href="/{{ .Board.Name }}">Return</a>]
-{{ $actor := .Board.Actor.Id }}
-{{ $board := .Board }}
-{{ $key := .Key }}
-{{ if .IsLocal }}
+</div>
+[<a href="/{{ .page.Board.Name }}">Return</a>]
+{{ $actor := .page.Board.Actor.Id }}
+{{ $board := .page.Board }}
+{{ $key := .page.Key }}
+{{ if .page.IsLocal }}
<div id="following" class="box2" style="margin-bottom: 25px; margin-top: 5px; padding: 12px;">
<h4 style="margin: 0; margin-bottom: 5px;">Following</h4>
- [{{ if .AutoSubscribe }}<a title="Auto Follow is On" href="/autosubscribe?board={{ .Board.Name }}">Toggle Auto Follow Off{{ else }}<a title="Auto Follow is Off" href="/autosubscribe?board={{ .Board.Name }}">Toggle Auto Follow On{{ end }}</a>]
- <form id="follow-form" action="/{{ .Key }}/{{ .Board.Name }}/follow" method="post" enctype="application/x-www-form-urlencoded" style="margin-top: 5px;">
+ [{{ if .page.AutoSubscribe }}<a title="Auto Follow is On" href="/autosubscribe?board={{ .page.Board.Name }}">Toggle Auto Follow Off{{ else }}<a title="Auto Follow is Off" href="/autosubscribe?board={{ .page.Board.Name }}">Toggle Auto Follow On{{ end }}</a>]
+ <form id="follow-form" action="/{{ .page.Key }}/{{ .page.Board.Name }}/follow" method="post" enctype="application/x-www-form-urlencoded" style="margin-top: 5px;">
<input id="follow" name="follow" style="margin-bottom: 5px;" size="35" placeholder="https://fchan.xyz/g"></input>
<input type="submit" value="Follow"><br>
- <input type="hidden" name="actor" value="{{ $board.Actor.Id }}">
+ <input type="hidden" name="actor" value="{{ $board.Actor.Id }}">
</form>
<div style="margin-bottom: 12px; color: grey;">also https://fchan.xyz/g/following or https://fchan.xyz/g/followers</div>
<ul style="display: inline-block; padding: 0; margin: 0; list-style-type: none;">
- {{ range .Following }}
+ {{ range .page.Following }}
<li>[<a href="/{{ $key }}/{{ $board.Name }}/follow?follow={{ . }}&actor={{ $actor }}">Unsubscribe</a>]<a href="{{ . }}">{{ . }}</a></li>
{{ end }}
</ul>
@@ -39,34 +33,33 @@
<div id="followers" class="box2" style="margin-bottom: 25px; padding: 12px;">
<h4 style="margin: 0; margin-bottom: 5px;">Followers</h4>
<ul style="display: inline-block; padding: 0; margin: 0; list-style-type: none;">
- {{ range .Followers }}
+ {{ range .page.Followers }}
<li><a href="{{ . }}">{{ . }}</a></li>
- {{ end }}
- </ul>
+ {{ end }}
+ </ul>
</div>
{{ end }}
<div id="reported" class="box2" style="margin-bottom: 25px; padding: 12px;">
<h4 style="margin: 0; margin-bottom: 5px;">Reported</h4>
<ul style="display: inline-block; padding: 0; margin: 0; list-style-type: none;">
- {{ $domain := .Domain }}
- {{ range .Reported }}
+ {{ $domain := .page.Domain }}
+ {{ range .page.Reported }}
<li><a id="rpost" post="{{ .ID }}" href=""></a> - <b>{{ .Count }}</b><span> "{{ .Reason }}" </span> [<a href="/delete?id={{ .ID }}&board={{ $board.Name }}&manage=t">Remove Post</a>] [<a href="/deleteattach?id={{ .ID }}&board={{ $board.Name }}&manage=t">Remove Attachment</a>] [<a href="/report?id={{ .ID }}&close=1&board={{ $board.Name }}">Close</a>]</li>
{{ end }}
- </ul>
+ </ul>
</div>
-{{ end }}
-{{ define "bottom" }}{{ end }}
-{{ define "script" }}
+{{ template "partials/footer" .page }}
+{{ template "partials/general_scripts" .page }}
+
<script>
var reported = document.querySelectorAll('#rpost');
var reportedArray = [].slice.call(reported);
reportedArray.forEach(function(r, i){
var id = r.getAttribute("post")
- r.innerText = "/" + {{ .Board.Name }} + "/" + shortURL("{{ .Board.Actor.Id }}", id)
- r.href = {{ .Domain }} + "/" + {{ .Board.Name }} + "/" + shortURL("{{ .Board.Actor.Id }}", id)
- })
+ r.innerText = "/" + {{ .page.Board.Name }} + "/" + shortURL("{{ .page.Board.Actor.Id }}", id)
+ r.href = {{ .page.Domain }} + "/" + {{ .page.Board.Name }} + "/" + shortURL("{{ .page.Board.Actor.Id }}", id)
+ })
</script>
-{{ end }}
diff --git a/webfinger/comm.go b/webfinger/comm.go
index 35ad335..ed20779 100644
--- a/webfinger/comm.go
+++ b/webfinger/comm.go
@@ -37,7 +37,6 @@ func GetActorCollection(collection string) (activitypub.Collection, error) {
if resp.StatusCode == 200 {
body, _ := ioutil.ReadAll(resp.Body)
-
if len(body) > 0 {
if err := json.Unmarshal(body, &nCollection); err != nil {
return nCollection, err