123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915 |
- package service
- import (
- "encoding/json"
- "fmt"
- "log"
- "mime/multipart"
- "net/http"
- "strconv"
- "time"
- "bloat/mastodon"
- "bloat/model"
- "github.com/gorilla/mux"
- )
- const (
- HTML int = iota
- JSON
- )
- const (
- NOAUTH int = iota
- SESSION
- CSRF
- )
- const csp = "default-src 'none';" +
- " img-src *;" +
- " media-src *;" +
- " font-src *;" +
- " child-src *;" +
- " connect-src 'self';" +
- " script-src 'self';" +
- " style-src 'self'"
- func NewHandler(s *service, verbose bool, staticDir string) http.Handler {
- r := mux.NewRouter()
- writeError := func(c *client, err error, t int, retry bool) {
- switch t {
- case HTML:
- c.w.WriteHeader(http.StatusInternalServerError)
- s.ErrorPage(c, err, retry)
- case JSON:
- c.w.WriteHeader(http.StatusInternalServerError)
- json.NewEncoder(c.w).Encode(map[string]string{
- "error": err.Error(),
- })
- }
- }
- handle := func(f func(c *client) error, at int, rt int) http.HandlerFunc {
- return func(w http.ResponseWriter, req *http.Request) {
- var err error
- c := &client{
- ctx: req.Context(),
- w: w,
- r: req,
- }
- if verbose {
- defer func(begin time.Time) {
- log.Printf("path=%s, err=%v, took=%v\n",
- req.URL.Path, err, time.Since(begin))
- }(time.Now())
- }
- h := c.w.Header()
- switch rt {
- case HTML:
- h.Set("Content-Type", "text/html; charset=utf-8")
- h.Set("Content-Security-Policy", csp)
- case JSON:
- h.Set("Content-Type", "application/json")
- }
- err = c.authenticate(at, s.instance)
- if err != nil {
- writeError(c, err, rt, req.Method == http.MethodGet)
- return
- }
- // Override the CSP header to allow custom CSS
- if rt == HTML && len(c.s.Settings.CSS) > 0 &&
- len(c.s.Settings.CSSHash) > 0 {
- v := fmt.Sprintf("%s 'sha256-%s'", csp, c.s.Settings.CSSHash)
- h.Set("Content-Security-Policy", v)
- }
- err = f(c)
- if err != nil {
- writeError(c, err, rt, req.Method == http.MethodGet)
- return
- }
- }
- }
- rootPage := handle(func(c *client) error {
- err := c.authenticate(SESSION, "")
- if err != nil {
- if err == errInvalidSession {
- c.redirect("/signin")
- return nil
- }
- return err
- }
- if !c.s.IsLoggedIn() {
- c.redirect("/signin")
- return nil
- }
- return s.RootPage(c)
- }, NOAUTH, HTML)
- navPage := handle(func(c *client) error {
- return s.NavPage(c)
- }, SESSION, HTML)
- signinPage := handle(func(c *client) error {
- instance, ok := s.SingleInstance()
- if !ok {
- return s.SigninPage(c)
- }
- url, sess, err := s.NewSession(c, instance)
- if err != nil {
- return err
- }
- c.setSession(sess)
- c.redirect(url)
- return nil
- }, NOAUTH, HTML)
- timelinePage := handle(func(c *client) error {
- tType, _ := mux.Vars(c.r)["type"]
- q := c.r.URL.Query()
- instance := q.Get("instance")
- list := q.Get("list")
- maxID := q.Get("max_id")
- minID := q.Get("min_id")
- tag := q.Get("tag")
- instance_type := q.Get("instance_type")
- return s.TimelinePage(c, tType, instance, list, maxID, minID, tag, instance_type)
- }, SESSION, HTML)
- defaultTimelinePage := handle(func(c *client) error {
- c.redirect("/timeline/home")
- return nil
- }, SESSION, HTML)
- threadPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- q := c.r.URL.Query()
- reply := q.Get("reply")
- return s.ThreadPage(c, id, len(reply) > 1)
- }, SESSION, HTML)
- quickReplyPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- return s.QuickReplyPage(c, id)
- }, SESSION, HTML)
- likedByPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- return s.LikedByPage(c, id)
- }, SESSION, HTML)
-
- reactedByPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- return s.ReactedByPage(c, id)
- }, SESSION, HTML)
- retweetedByPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- return s.RetweetedByPage(c, id)
- }, SESSION, HTML)
- notificationsPage := handle(func(c *client) error {
- q := c.r.URL.Query()
- maxID := q.Get("max_id")
- minID := q.Get("min_id")
- return s.NotificationPage(c, maxID, minID)
- }, SESSION, HTML)
- userPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- pageType, _ := mux.Vars(c.r)["type"]
- q := c.r.URL.Query()
- maxID := q.Get("max_id")
- minID := q.Get("min_id")
- return s.UserPage(c, id, pageType, maxID, minID)
- }, SESSION, HTML)
- userSearchPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- q := c.r.URL.Query()
- sq := q.Get("q")
- offset, _ := strconv.Atoi(q.Get("offset"))
- return s.UserSearchPage(c, id, sq, offset)
- }, SESSION, HTML)
- mutePage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- return s.MutePage(c, id)
- }, SESSION, HTML)
- aboutPage := handle(func(c *client) error {
- return s.AboutPage(c)
- }, SESSION, HTML)
-
- aboutInstance := handle(func(c *client) error {
- return s.AboutInstance(c)
- }, SESSION, HTML)
- emojisPage := handle(func(c *client) error {
- return s.EmojiPage(c)
- }, SESSION, HTML)
- searchPage := handle(func(c *client) error {
- q := c.r.URL.Query()
- sq := q.Get("q")
- qType := q.Get("type")
- offset, _ := strconv.Atoi(q.Get("offset"))
- return s.SearchPage(c, sq, qType, offset)
- }, SESSION, HTML)
- settingsPage := handle(func(c *client) error {
- return s.SettingsPage(c)
- }, SESSION, HTML)
- filtersPage := handle(func(c *client) error {
- return s.FiltersPage(c)
- }, SESSION, HTML)
- profilePage := handle(func(c *client) error {
- return s.ProfilePage(c)
- }, SESSION, HTML)
- profileUpdate := handle(func(c *client) error {
- name := c.r.FormValue("name")
- bio := c.r.FormValue("bio")
- var avatar, banner *multipart.FileHeader
- if f := c.r.MultipartForm.File["avatar"]; len(f) > 0 {
- avatar = f[0]
- }
- if f := c.r.MultipartForm.File["banner"]; len(f) > 0 {
- banner = f[0]
- }
- var fields []mastodon.Field
- for i := 0; i < 16; i++ {
- n := c.r.FormValue(fmt.Sprintf("field-name-%d", i))
- v := c.r.FormValue(fmt.Sprintf("field-value-%d", i))
- if len(n) == 0 {
- continue
- }
- f := mastodon.Field{Name: n, Value: v}
- fields = append(fields, f)
- }
- locked := c.r.FormValue("locked") == "true"
- err := s.ProfileUpdate(c, name, bio, avatar, banner, fields, locked)
- if err != nil {
- return err
- }
- c.redirect("/")
- return nil
- }, CSRF, HTML)
- profileDelAvatar := handle(func(c *client) error {
- err := s.ProfileDelAvatar(c)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- profileDelBanner := handle(func(c *client) error {
- err := s.ProfileDelBanner(c)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- signin := handle(func(c *client) error {
- instance := c.r.FormValue("instance")
- url, sess, err := s.NewSession(c, instance)
- if err != nil {
- return err
- }
- c.setSession(sess)
- c.redirect(url)
- return nil
- }, NOAUTH, HTML)
- oauthCallback := handle(func(c *client) error {
- q := c.r.URL.Query()
- token := q.Get("code")
- err := s.Signin(c, token)
- if err != nil {
- return err
- }
- c.redirect("/")
- return nil
- }, SESSION, HTML)
- post := handle(func(c *client) error {
- spoilerText := c.r.FormValue("title")
- content := c.r.FormValue("content")
- replyToID := c.r.FormValue("reply_to_id")
- format := c.r.FormValue("format")
- visibility := c.r.FormValue("visibility")
- isNSFW := c.r.FormValue("is_nsfw") == "true"
- quickReply := c.r.FormValue("quickreply") == "true"
- files := c.r.MultipartForm.File["attachments"]
- var mediaDescription []string
- for i := 0; i < len(files); i++ {
- v := c.r.FormValue(fmt.Sprintf("media-descr-%d", i))
- mediaDescription = append(mediaDescription, v)
- }
- edit := c.r.FormValue("edit-status-id")
- language := c.r.FormValue("lang-code")
- expiresIn, err := strconv.Atoi(c.r.FormValue("expires-in"))
- if err != nil {
- return err
- }
- scheduledAt := c.r.FormValue("scheduled")
- if scheduledAt != "" {
- scheduled, err := time.Parse("2006-01-02T15:04", scheduledAt)
- if err != nil {
- return err
- }
- scheduledAt = string(scheduled.UTC().Format(time.RFC3339))
- }
- var pollOptions []string
- for i := 0; i < 20; i++ {
- v := c.r.FormValue(fmt.Sprintf("poll-option-%d", i))
- if len(v) == 0 {
- continue
- }
- pollOptions = append(pollOptions, v)
- }
- pollExpiresIn, err := strconv.Atoi(c.r.FormValue("poll-expires-in"))
- if err != nil {
- return err
- }
- pollHideTotals := c.r.FormValue("poll-hide-totals") == "true"
- pollMultiple := c.r.FormValue("poll-is-multiple") == "true"
- id, err := s.Post(c, content, replyToID, format, visibility, isNSFW, spoilerText, files, edit, language, expiresIn, scheduledAt, pollOptions, pollExpiresIn, pollHideTotals, pollMultiple, mediaDescription)
- if err != nil {
- return err
- }
- var location string
- if len(replyToID) > 0 {
- if quickReply {
- location = "/quickreply/" + id + "#status-" + id
- } else {
- location = "/thread/" + replyToID + "#status-" + id
- }
- } else {
- location = c.r.FormValue("referrer")
- }
- c.redirect(location)
- return nil
- }, CSRF, HTML)
- like := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- rid := c.r.FormValue("retweeted_by_id")
- _, err := s.Like(c, id)
- if err != nil {
- return err
- }
- if len(rid) > 0 {
- id = rid
- }
- c.redirect(c.r.FormValue("referrer") + "#status-" + id)
- return nil
- }, CSRF, HTML)
- unlike := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- rid := c.r.FormValue("retweeted_by_id")
- _, err := s.UnLike(c, id)
- if err != nil {
- return err
- }
- if len(rid) > 0 {
- id = rid
- }
- c.redirect(c.r.FormValue("referrer") + "#status-" + id)
- return nil
- }, CSRF, HTML)
- putreact := handle(func(c *client) error {
- q := c.r.URL.Query()
- emoji := q.Get("emoji")
- if len(emoji) <= 0 {
- emoji = c.r.FormValue("akkoma-reaction")
- }
- id, _ := mux.Vars(c.r)["id"]
- _, err := s.PutReact(c, id, emoji)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer")+"#status-"+id)
- return nil
- }, CSRF, HTML)
- unreact := handle(func(c *client) error {
- q := c.r.URL.Query()
- emoji := q.Get("emoji")
- id, _ := mux.Vars(c.r)["id"]
- _, err := s.UnReact(c, id, emoji)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer")+"#status-"+id)
- return nil
- }, CSRF, HTML)
- retweet := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- rid := c.r.FormValue("retweeted_by_id")
- visibility := c.r.FormValue("retweet_visibility")
- _, err := s.Retweet(c, id, visibility)
- if err != nil {
- return err
- }
- if len(rid) > 0 {
- id = rid
- }
- c.redirect(c.r.FormValue("referrer") + "#status-" + id)
- return nil
- }, CSRF, HTML)
- unretweet := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- rid := c.r.FormValue("retweeted_by_id")
- _, err := s.UnRetweet(c, id)
- if err != nil {
- return err
- }
- if len(rid) > 0 {
- id = rid
- }
- c.redirect(c.r.FormValue("referrer") + "#status-" + id)
- return nil
- }, CSRF, HTML)
- vote := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- statusID := c.r.FormValue("status_id")
- choices, _ := c.r.PostForm["choices"]
- err := s.Vote(c, id, choices)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer") + "#status-" + statusID)
- return nil
- }, CSRF, HTML)
- follow := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- q := c.r.URL.Query()
- var reblogs *bool
- if r, ok := q["reblogs"]; ok && len(r) > 0 {
- reblogs = new(bool)
- *reblogs = r[0] == "true"
- }
- err := s.Follow(c, id, reblogs)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- unfollow := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.UnFollow(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- accept := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.Accept(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- reject := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.Reject(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- mute := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- notifications, _ := strconv.ParseBool(c.r.FormValue("notifications"))
- duration, _ := strconv.Atoi(c.r.FormValue("duration"))
- err := s.Mute(c, id, notifications, duration)
- if err != nil {
- return err
- }
- c.redirect("/user/" + id)
- return nil
- }, CSRF, HTML)
- unMute := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.UnMute(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- block := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.Block(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- unBlock := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.UnBlock(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- subscribe := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.Subscribe(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- unSubscribe := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.UnSubscribe(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- settings := handle(func(c *client) error {
- visibility := c.r.FormValue("visibility")
- format := c.r.FormValue("format")
- copyScope := c.r.FormValue("copy_scope") == "true"
- threadInNewTab := c.r.FormValue("thread_in_new_tab") == "true"
- hideAttachments := c.r.FormValue("hide_attachments") == "true"
- maskNSFW := c.r.FormValue("mask_nsfw") == "true"
- ni, _ := strconv.Atoi(c.r.FormValue("notification_interval"))
- fluorideMode := c.r.FormValue("fluoride_mode") == "true"
- darkMode := c.r.FormValue("dark_mode") == "true"
- antiDopamineMode := c.r.FormValue("anti_dopamine_mode") == "true"
- hideUnsupportedNotifs := c.r.FormValue("hide_unsupported_notifs") == "true"
- instanceEmojiFilter := c.r.FormValue("instance-emoji-filter")
- addReactionsFilter := c.r.FormValue("pleroma-reactions-filter")
- css := c.r.FormValue("css")
- settings := &model.Settings{
- DefaultVisibility: visibility,
- DefaultFormat: format,
- CopyScope: copyScope,
- ThreadInNewTab: threadInNewTab,
- HideAttachments: hideAttachments,
- MaskNSFW: maskNSFW,
- NotificationInterval: ni,
- FluorideMode: fluorideMode,
- DarkMode: darkMode,
- AntiDopamineMode: antiDopamineMode,
- HideUnsupportedNotifs: hideUnsupportedNotifs,
- InstanceEmojiFilter: instanceEmojiFilter,
- AddReactionsFilter: addReactionsFilter,
- CSS: css,
- }
- err := s.SaveSettings(c, settings)
- if err != nil {
- return err
- }
- c.redirect("/")
- return nil
- }, CSRF, HTML)
- muteConversation := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.MuteConversation(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- unMuteConversation := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.UnMuteConversation(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- pin := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.Pin(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- unpin := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.UnPin(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- delete := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.Delete(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- readNotifications := handle(func(c *client) error {
- q := c.r.URL.Query()
- maxID := q.Get("max_id")
- err := s.ReadNotifications(c, maxID)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- bookmark := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- rid := c.r.FormValue("retweeted_by_id")
- err := s.Bookmark(c, id)
- if err != nil {
- return err
- }
- if len(rid) > 0 {
- id = rid
- }
- c.redirect(c.r.FormValue("referrer") + "#status-" + id)
- return nil
- }, CSRF, HTML)
- unBookmark := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- rid := c.r.FormValue("retweeted_by_id")
- err := s.UnBookmark(c, id)
- if err != nil {
- return err
- }
- if len(rid) > 0 {
- id = rid
- }
- c.redirect(c.r.FormValue("referrer") + "#status-" + id)
- return nil
- }, CSRF, HTML)
- filter := handle(func(c *client) error {
- phrase := c.r.FormValue("phrase")
- wholeWord := c.r.FormValue("whole_word") == "true"
- err := s.Filter(c, phrase, wholeWord)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- unFilter := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.UnFilter(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- listsPage := handle(func(c *client) error {
- return s.ListsPage(c)
- }, SESSION, HTML)
- addList := handle(func(c *client) error {
- title := c.r.FormValue("title")
- err := s.AddList(c, title)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- removeList := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- err := s.RemoveList(c, id)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- renameList := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- title := c.r.FormValue("title")
- err := s.RenameList(c, id, title)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- listPage := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- q := c.r.URL.Query()
- sq := q.Get("q")
- return s.ListPage(c, id, sq)
- }, SESSION, HTML)
- listAddUser := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- q := c.r.URL.Query()
- uid := q.Get("uid")
- if uid == "" {
- uid = c.r.FormValue("uid")
- }
- err := s.ListAddUser(c, id, uid)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- listRemoveUser := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- q := c.r.URL.Query()
- uid := q.Get("uid")
- err := s.ListRemoveUser(c, id, uid)
- if err != nil {
- return err
- }
- c.redirect(c.r.FormValue("referrer"))
- return nil
- }, CSRF, HTML)
- signout := handle(func(c *client) error {
- err := s.Signout(c)
- if err != nil {
- return err
- }
- c.unsetSession()
- c.redirect("/")
- return nil
- }, CSRF, HTML)
- fLike := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- count, err := s.Like(c, id)
- if err != nil {
- return err
- }
- return c.writeJson(count)
- }, CSRF, JSON)
- fUnlike := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- count, err := s.UnLike(c, id)
- if err != nil {
- return err
- }
- return c.writeJson(count)
- }, CSRF, JSON)
- fRetweet := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- visibility := c.r.FormValue("retweet_visibility")
- count, err := s.Retweet(c, id, visibility)
- if err != nil {
- return err
- }
- return c.writeJson(count)
- }, CSRF, JSON)
- fUnretweet := handle(func(c *client) error {
- id, _ := mux.Vars(c.r)["id"]
- count, err := s.UnRetweet(c, id)
- if err != nil {
- return err
- }
- return c.writeJson(count)
- }, CSRF, JSON)
- r.HandleFunc("/", rootPage).Methods(http.MethodGet)
- r.HandleFunc("/nav", navPage).Methods(http.MethodGet)
- r.HandleFunc("/signin", signinPage).Methods(http.MethodGet)
- r.HandleFunc("/timeline/{type}", timelinePage).Methods(http.MethodGet)
- r.HandleFunc("/timeline", defaultTimelinePage).Methods(http.MethodGet)
- r.HandleFunc("/thread/{id}", threadPage).Methods(http.MethodGet)
- r.HandleFunc("/quickreply/{id}", quickReplyPage).Methods(http.MethodGet)
- r.HandleFunc("/likedby/{id}", likedByPage).Methods(http.MethodGet)
- r.HandleFunc("/reactionspage/{id}", reactedByPage).Methods(http.MethodGet)
- r.HandleFunc("/retweetedby/{id}", retweetedByPage).Methods(http.MethodGet)
- r.HandleFunc("/notifications", notificationsPage).Methods(http.MethodGet)
- r.HandleFunc("/user/{id}", userPage).Methods(http.MethodGet)
- r.HandleFunc("/user/{id}/{type}", userPage).Methods(http.MethodGet)
- r.HandleFunc("/usersearch/{id}", userSearchPage).Methods(http.MethodGet)
- r.HandleFunc("/mute/{id}", mutePage).Methods(http.MethodGet)
- r.HandleFunc("/about", aboutPage).Methods(http.MethodGet)
- r.HandleFunc("/aboutinstance", aboutInstance).Methods(http.MethodGet)
- r.HandleFunc("/emojis", emojisPage).Methods(http.MethodGet)
- r.HandleFunc("/search", searchPage).Methods(http.MethodGet)
- r.HandleFunc("/settings", settingsPage).Methods(http.MethodGet)
- r.HandleFunc("/filters", filtersPage).Methods(http.MethodGet)
- r.HandleFunc("/profile", profilePage).Methods(http.MethodGet)
- r.HandleFunc("/profile", profileUpdate).Methods(http.MethodPost)
- r.HandleFunc("/profile/delavatar", profileDelAvatar).Methods(http.MethodPost)
- r.HandleFunc("/profile/delbanner", profileDelBanner).Methods(http.MethodPost)
- r.HandleFunc("/signin", signin).Methods(http.MethodPost)
- r.HandleFunc("/oauth_callback", oauthCallback).Methods(http.MethodGet)
- r.HandleFunc("/post", post).Methods(http.MethodPost)
- r.HandleFunc("/like/{id}", like).Methods(http.MethodPost)
- r.HandleFunc("/unlike/{id}", unlike).Methods(http.MethodPost)
- r.HandleFunc("/react-with/{id}", putreact).Methods(http.MethodPost)
- r.HandleFunc("/unreact-with/{id}", unreact).Methods(http.MethodPost)
- r.HandleFunc("/retweet/{id}", retweet).Methods(http.MethodPost)
- r.HandleFunc("/unretweet/{id}", unretweet).Methods(http.MethodPost)
- r.HandleFunc("/vote/{id}", vote).Methods(http.MethodPost)
- r.HandleFunc("/follow/{id}", follow).Methods(http.MethodPost)
- r.HandleFunc("/unfollow/{id}", unfollow).Methods(http.MethodPost)
- r.HandleFunc("/accept/{id}", accept).Methods(http.MethodPost)
- r.HandleFunc("/reject/{id}", reject).Methods(http.MethodPost)
- r.HandleFunc("/mute/{id}", mute).Methods(http.MethodPost)
- r.HandleFunc("/unmute/{id}", unMute).Methods(http.MethodPost)
- r.HandleFunc("/block/{id}", block).Methods(http.MethodPost)
- r.HandleFunc("/unblock/{id}", unBlock).Methods(http.MethodPost)
- r.HandleFunc("/subscribe/{id}", subscribe).Methods(http.MethodPost)
- r.HandleFunc("/unsubscribe/{id}", unSubscribe).Methods(http.MethodPost)
- r.HandleFunc("/settings", settings).Methods(http.MethodPost)
- r.HandleFunc("/muteconv/{id}", muteConversation).Methods(http.MethodPost)
- r.HandleFunc("/unmuteconv/{id}", unMuteConversation).Methods(http.MethodPost)
- r.HandleFunc("/pin/{id}", pin).Methods(http.MethodPost)
- r.HandleFunc("/unpin/{id}", unpin).Methods(http.MethodPost)
- r.HandleFunc("/delete/{id}", delete).Methods(http.MethodPost)
- r.HandleFunc("/notifications/read", readNotifications).Methods(http.MethodPost)
- r.HandleFunc("/bookmark/{id}", bookmark).Methods(http.MethodPost)
- r.HandleFunc("/unbookmark/{id}", unBookmark).Methods(http.MethodPost)
- r.HandleFunc("/filter", filter).Methods(http.MethodPost)
- r.HandleFunc("/unfilter/{id}", unFilter).Methods(http.MethodPost)
- r.HandleFunc("/lists", listsPage).Methods(http.MethodGet)
- r.HandleFunc("/list", addList).Methods(http.MethodPost)
- r.HandleFunc("/list/{id}", listPage).Methods(http.MethodGet)
- r.HandleFunc("/list/{id}/remove", removeList).Methods(http.MethodPost)
- r.HandleFunc("/list/{id}/rename", renameList).Methods(http.MethodPost)
- r.HandleFunc("/list/{id}/adduser", listAddUser).Methods(http.MethodPost)
- r.HandleFunc("/list/{id}/removeuser", listRemoveUser).Methods(http.MethodPost)
- r.HandleFunc("/signout", signout).Methods(http.MethodPost)
- r.HandleFunc("/fluoride/like/{id}", fLike).Methods(http.MethodPost)
- r.HandleFunc("/fluoride/unlike/{id}", fUnlike).Methods(http.MethodPost)
- r.HandleFunc("/fluoride/retweet/{id}", fRetweet).Methods(http.MethodPost)
- r.HandleFunc("/fluoride/unretweet/{id}", fUnretweet).Methods(http.MethodPost)
- r.PathPrefix("/static").Handler(http.StripPrefix("/static",
- http.FileServer(http.Dir(staticDir))))
- return r
- }
|