- Add proxy endpoint for proxying a message to a target's inbox - Change duck embed to fs based to fix mk not understanding it
This commit is contained in:
parent
d70786439e
commit
415cd89792
8 changed files with 104 additions and 17 deletions
4
main.go
4
main.go
|
@ -39,6 +39,9 @@ var nojsFS embed.FS
|
|||
//go:embed duck.webp
|
||||
var defaultDuck string
|
||||
|
||||
//go:embed duck.webp
|
||||
var duckFS embed.FS
|
||||
|
||||
func main() {
|
||||
other.SetupFlags()
|
||||
flag.Parse()
|
||||
|
@ -167,6 +170,7 @@ func newServer() {
|
|||
public := webpublic.New(
|
||||
fmt.Sprintf(":%v", config.GlobalConfig.General.PrivatePort),
|
||||
&defaultDuck,
|
||||
duckFS,
|
||||
)
|
||||
if err = public.Start(); err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to start public server")
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# .
|
||||
[general]
|
||||
protocol = "https"
|
||||
domain = "serveo.net"
|
||||
subdomain = "5dc9c90be02fecb3b132ad4d4877555a"
|
||||
subdomain = "e8f7573481d6b2311fb076f4190ac852"
|
||||
private_port = 8080
|
||||
public_port = 443
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ func New(addr string) *Server {
|
|||
handler.HandleFunc("GET /import-user", issueUserImport)
|
||||
handler.HandleFunc("GET /keys-for", returnKeypair)
|
||||
handler.HandleFunc("GET /import-server", importServerInfo)
|
||||
handler.HandleFunc("GET /request-follow", kickoffFollow)
|
||||
handler.HandleFunc("POST /send-as", proxyMessageToTarget)
|
||||
web := http.Server{
|
||||
Addr: addr,
|
||||
Handler: webutils.ChainMiddlewares(
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
@ -206,13 +207,78 @@ func returnKeypair(w http.ResponseWriter, r *http.Request) {
|
|||
func issueUserImport(w http.ResponseWriter, r *http.Request) {
|
||||
target := r.FormValue("target")
|
||||
_, err := activitypub.ImportRemoteAccountByHandle(target)
|
||||
hlog.FromRequest(r).Info().Err(err).Msg("Err from import request")
|
||||
if err != nil {
|
||||
hlog.FromRequest(r).Info().Err(err).Msg("Err from import request")
|
||||
}
|
||||
}
|
||||
|
||||
func proxyMessageToTarget(w http.ResponseWriter, r *http.Request) {
|
||||
type Inbound struct {
|
||||
From string `json:"from"`
|
||||
Target string `json:"target"`
|
||||
Message any `json:"message"`
|
||||
}
|
||||
log := hlog.FromRequest(r)
|
||||
data := Inbound{}
|
||||
dec := json.NewDecoder(r.Body)
|
||||
err := dec.Decode(&data)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to decode json body")
|
||||
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
log.Debug().Any("data", data).Msg("Received message")
|
||||
user, err := dbgen.User.GetByUsername(data.From)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get user from storage")
|
||||
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
targetId, err := activitypub.ImportRemoteAccountByHandle(data.Target)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to import target user")
|
||||
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
target, err := dbgen.User.Where(dbgen.User.ID.Eq(targetId)).
|
||||
Preload(dbgen.User.RemoteInfo).
|
||||
First()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get target user from db")
|
||||
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
outBody, err := json.Marshal(data.Message)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to marshal out data")
|
||||
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
log.Debug().Bytes("request-body", outBody).Msg("Body of proxied request")
|
||||
response, err := webshared.RequestSignedCavage(
|
||||
"POST",
|
||||
target.RemoteInfo.InboxLink,
|
||||
outBody,
|
||||
user,
|
||||
)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Request failed")
|
||||
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer response.Body.Close()
|
||||
respBody, _ := io.ReadAll(response.Body)
|
||||
log.Debug().
|
||||
Int("status-code", response.StatusCode).
|
||||
Bytes("body", respBody).
|
||||
Msg("Response from message")
|
||||
}
|
||||
|
||||
func kickoffFollow(w http.ResponseWriter, r *http.Request) {
|
||||
type Inbound struct {
|
||||
Id string
|
||||
Target string
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
}
|
||||
var data Inbound
|
||||
dec := json.NewDecoder(r.Body)
|
||||
|
|
|
@ -44,8 +44,6 @@ func BuildAuthorizedFetchCheck(forNonGet bool, forGet bool) webutils.HandlerBuil
|
|||
return func(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
log := hlog.FromRequest(r)
|
||||
log.Info().Msg("AuthFetch middleware")
|
||||
defer log.Info().Msg("AuhFetch completed")
|
||||
path := r.URL.Path
|
||||
// Check always open path first
|
||||
for _, re := range publicPaths {
|
||||
|
|
|
@ -29,6 +29,7 @@ package webpublic
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
|
||||
webutils "git.mstar.dev/mstar/goutils/http"
|
||||
|
@ -41,7 +42,7 @@ type Server struct {
|
|||
server *http.Server
|
||||
}
|
||||
|
||||
func New(addr string, duckImg *string) *Server {
|
||||
func New(addr string, duckImg *string, duckFs fs.FS) *Server {
|
||||
handler := http.NewServeMux()
|
||||
handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(500)
|
||||
|
@ -53,11 +54,8 @@ func New(addr string, duckImg *string) *Server {
|
|||
handler.HandleFunc("GET /nodeinfo/2.1", api.NodeInfo21)
|
||||
handler.HandleFunc("GET /nodeinfo/2.0", api.NodeInfo20)
|
||||
handler.HandleFunc("GET /errors/{name}", errorTypeHandler)
|
||||
handler.HandleFunc("GET /default-image", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Content-Type", "image/web")
|
||||
w.Header().Add("Content-Disposition", "attachment; filename=\"duck.webp\"")
|
||||
fmt.Fprint(w, *duckImg)
|
||||
})
|
||||
handler.HandleFunc("GET /default-image", buildServeDefaultImage(duckImg, duckFs))
|
||||
handler.HandleFunc("GET /default-image.webp", buildServeDefaultImage(duckImg, duckFs))
|
||||
server := http.Server{
|
||||
Handler: webutils.ChainMiddlewares(
|
||||
handler,
|
||||
|
@ -76,3 +74,15 @@ func (s *Server) Start() error {
|
|||
func (s *Server) Stop() error {
|
||||
return s.server.Shutdown(context.Background())
|
||||
}
|
||||
|
||||
func buildServeDefaultImage(
|
||||
duckImg *string,
|
||||
duckFs fs.FS,
|
||||
) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFileFS(w, r, duckFs, "duck.webp")
|
||||
// w.Header().Add("Content-Type", "image/webp")
|
||||
// w.Header().Add("Content-Disposition", "attachment; filename=\"duck.webp\"")
|
||||
// fmt.Fprint(w, *duckImg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,12 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"net/http"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/yaronf/httpsign"
|
||||
|
||||
"git.mstar.dev/mstar/linstrom/config"
|
||||
|
@ -77,11 +79,16 @@ func RequestSignedCavage(
|
|||
body []byte,
|
||||
actor *models.User,
|
||||
) (*http.Response, error) {
|
||||
req, err := NewRequest(method, target, nil)
|
||||
var bodyReader io.Reader
|
||||
if body != nil {
|
||||
bodyReader = bytes.NewReader(body)
|
||||
}
|
||||
req, err := NewRequest(method, target, bodyReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Accept", "application/activity+json")
|
||||
req.Header.Add("Content-Type", "application/activity+json")
|
||||
|
||||
var keyBytes []byte
|
||||
if config.GlobalConfig.Experimental.UseEd25519Keys {
|
||||
|
@ -101,6 +108,7 @@ func RequestSignedCavage(
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debug().Bytes("body", body).Any("headers", req.Header).Msg("Sending signed request")
|
||||
return RequestClient.Do(req)
|
||||
}
|
||||
|
||||
|
@ -119,7 +127,7 @@ func applyBodyHash(headers http.Header, body []byte) error {
|
|||
return nil
|
||||
}
|
||||
hash := sha256.Sum256(body)
|
||||
based := base64.StdEncoding.EncodeToString(hash[:])
|
||||
headers.Set("Digest", "SHA-256="+based)
|
||||
header := "SHA-256=" + base64.StdEncoding.EncodeToString(hash[:])
|
||||
headers.Set("Digest", header)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import "strings"
|
|||
// TODO: Define linstrom uri type
|
||||
|
||||
var hardcodedUrls = map[string]string{
|
||||
"default-media": "/default-image",
|
||||
"default-media": "/default-image.webp",
|
||||
}
|
||||
|
||||
func EnsurePublicUrl(rawUrl string) string {
|
||||
|
|
Loading…
Reference in a new issue