Introduced `lol.Tracer` for function entry/exit logging across various packages. This improves traceability and debugging of function executions while preserving existing behavior. Removed unused files `doc.go` and `nothing.go` to clean up the repository.
97 lines
2.8 KiB
Go
97 lines
2.8 KiB
Go
package openapi
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/danielgtaylor/huma/v2"
|
|
|
|
"realy.lol/chk"
|
|
"realy.lol/context"
|
|
"realy.lol/event"
|
|
"realy.lol/httpauth"
|
|
"realy.lol/lol"
|
|
"realy.lol/publish"
|
|
"realy.lol/realy/helpers"
|
|
)
|
|
|
|
// RelayInput is the parameters for the Event HTTP API method.
|
|
type RelayInput struct {
|
|
Auth string `header:"Authorization" doc:"nostr nip-98 (and expiring variant)" required:"false"`
|
|
RawBody []byte
|
|
}
|
|
|
|
// RelayOutput is the return parameters for the HTTP API Relay method.
|
|
type RelayOutput struct{ Body string }
|
|
|
|
// RegisterRelay is the implementation of the HTTP API Relay method.
|
|
func (x *Operations) RegisterRelay(api huma.API) {
|
|
lol.Tracer("RegisterRelay")
|
|
defer func() { lol.Tracer("end RegisterRelay") }()
|
|
name := "Relay"
|
|
description := "relay an event, don't store it"
|
|
path := x.path + "/relay"
|
|
scopes := []string{"user"}
|
|
method := http.MethodPost
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: name,
|
|
Summary: name,
|
|
Path: path,
|
|
Method: method,
|
|
Tags: []string{"events"},
|
|
Description: helpers.GenerateDescription(description, scopes),
|
|
Security: []map[string][]string{{"auth": scopes}},
|
|
}, func(ctx context.T, input *RelayInput) (output *RelayOutput, err error) {
|
|
lol.Tracer("Relay", input)
|
|
defer func() { lol.Tracer("end Relay", output, err) }()
|
|
r := ctx.Value("http-request").(*http.Request)
|
|
remote := helpers.GetRemoteFromReq(r)
|
|
var valid bool
|
|
var pubkey []byte
|
|
valid, pubkey, err = httpauth.CheckAuth(r)
|
|
// if there is an error but not that the token is missing, or there is no error
|
|
// but the signature is invalid, return error that request is unauthorized.
|
|
if err != nil && !errors.Is(err, httpauth.ErrMissingKey) {
|
|
err = huma.Error400BadRequest(err.Error())
|
|
return
|
|
}
|
|
err = nil
|
|
if !valid {
|
|
err = huma.Error401Unauthorized("Authorization header is invalid")
|
|
return
|
|
}
|
|
var ok bool
|
|
// if there was auth, or no auth, check the relay policy allows accepting the
|
|
// event (no auth with auth required or auth not valid for action can apply
|
|
// here).
|
|
ev := &event.T{}
|
|
if _, err = ev.Unmarshal(input.RawBody); chk.E(err) {
|
|
err = huma.Error406NotAcceptable(err.Error())
|
|
return
|
|
}
|
|
accept, notice, _ := x.AcceptEvent(ctx, ev, r, pubkey, remote)
|
|
if !accept {
|
|
err = huma.Error401Unauthorized(notice)
|
|
return
|
|
}
|
|
if !bytes.Equal(ev.GetIDBytes(), ev.Id) {
|
|
err = huma.Error400BadRequest("event id is computed incorrectly")
|
|
return
|
|
}
|
|
if ok, err = ev.Verify(); chk.T(err) {
|
|
err = huma.Error400BadRequest("failed to verify signature")
|
|
return
|
|
} else if !ok {
|
|
err = huma.Error400BadRequest("signature is invalid")
|
|
return
|
|
}
|
|
var authRequired bool
|
|
|
|
authRequired = x.Server.AuthRequired()
|
|
|
|
publish.P.Deliver(authRequired, x.PublicReadable(), ev)
|
|
return
|
|
})
|
|
}
|