Compare commits

...

6 Commits

Author SHA1 Message Date
fiatjaf
d4334ac2bb revert "a function to send an event directly to a specific connection."
this reverts commit e9c9d0c3a7 because it is not a good idea and probably useless.
2024-10-16 15:07:55 -03:00
fiatjaf
9069341657 a context that is canceled whenever a websocket is dropped. 2024-10-16 15:06:47 -03:00
fiatjaf
9137eb02b0 cookbook: reacting to auth events. 2024-10-14 12:20:46 -03:00
fiatjaf
e9c9d0c3a7 a function to send an event directly to a specific connection. 2024-10-13 12:42:36 -03:00
fiatjaf
39d882857c fix missing ! in CheckID() 2024-09-25 14:34:04 -03:00
ptrio42 aka pitiunited
6e04cca511 Update use-cases.md 2024-09-25 08:01:35 -03:00
5 changed files with 40 additions and 7 deletions

View File

@@ -60,3 +60,26 @@ relay.RejectFilter = append(relay.RejectFilter, func(ctx context.Context, filter
}
})
```
## Reacting to a successful authentication
Each `khatru.WebSocket` object has an `.Authed` channel that is closed whenever that connection performs a successful authentication.
You can use that to emulate a listener for these events in case you want to keep track of who is authenticating in real time and not only check it when they request for something.
```go
relay.OnConnect = append(relay.OnConnect,
khatru.RequestAuth,
func(ctx context.Context) {
go func(ctx context.Context) {
conn := khatru.GetConnection(ctx)
select {
case <-ctx.Done():
fmt.Println("connection closed")
case <-conn.Authed:
fmt.Println("authenticated as", conn.AuthedPublicKey)
}
}(ctx)
},
)
```

View File

@@ -10,6 +10,7 @@
* [song](https://git.fiatjaf.com/song), a personal git server that comes with an embedded relay dedicated to dealing with [NIP-34](https://nips.nostr.com/34) git-related Nostr events
* [relay29](https://github.com/fiatjaf/relay29), a relay that powers most of the [NIP-29](https://nips.nostr.com/29) Nostr groups ecosystem
* [fiatjaf.com](https://fiatjaf.com), a personal website that serves the same content as HTML but also as Nostr events.
* [gm-relay](https://github.com/ptrio42/gm-relay), a relay that only accepts GM notes once a day.
## Other possible use cases

View File

@@ -53,6 +53,7 @@ func (rl *Relay) Shutdown(ctx context.Context) {
defer rl.clientsMutex.Unlock()
for ws := range rl.clients {
ws.conn.WriteControl(websocket.CloseMessage, nil, time.Now().Add(time.Second))
ws.cancel()
ws.conn.Close()
}
clear(rl.clients)

View File

@@ -58,6 +58,7 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
Request: r,
Challenge: hex.EncodeToString(challenge),
}
ws.Context, ws.cancel = context.WithCancel(context.Background())
rl.clientsMutex.Lock()
rl.clients[ws] = make([]listenerSpec, 0, 2)
@@ -77,7 +78,8 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
ticker.Stop()
cancel()
conn.Close()
ws.cancel()
ws.conn.Close()
rl.removeClientAndListeners(ws)
}
@@ -85,10 +87,10 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
go func() {
defer kill()
conn.SetReadLimit(rl.MaxMessageSize)
conn.SetReadDeadline(time.Now().Add(rl.PongWait))
conn.SetPongHandler(func(string) error {
conn.SetReadDeadline(time.Now().Add(rl.PongWait))
ws.conn.SetReadLimit(rl.MaxMessageSize)
ws.conn.SetReadDeadline(time.Now().Add(rl.PongWait))
ws.conn.SetPongHandler(func(string) error {
ws.conn.SetReadDeadline(time.Now().Add(rl.PongWait))
return nil
})
@@ -97,7 +99,7 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
}
for {
typ, message, err := conn.ReadMessage()
typ, message, err := ws.conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(
err,
@@ -109,6 +111,7 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
) {
rl.Log.Printf("unexpected close error from %s: %v\n", r.Header.Get("X-Forwarded-For"), err)
}
ws.cancel()
return
}
@@ -127,7 +130,7 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
switch env := envelope.(type) {
case *nostr.EventEnvelope:
// check id
if env.Event.CheckID() {
if !env.Event.CheckID() {
ws.WriteJSON(nostr.OKEnvelope{EventID: env.Event.ID, OK: false, Reason: "invalid: id is computed incorrectly"})
return
}

View File

@@ -1,6 +1,7 @@
package khatru
import (
"context"
"net/http"
"sync"
@@ -14,6 +15,10 @@ type WebSocket struct {
// original request
Request *http.Request
// this Context will be canceled whenever the connection is closed from the client side or server-side.
Context context.Context
cancel context.CancelFunc
// nip42
Challenge string
AuthedPublicKey string