✨ E2EE Key Exchange
This commit is contained in:
		@@ -1,25 +0,0 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"git.solsynth.dev/hydrogen/passport/pkg/models"
 | 
			
		||||
	"git.solsynth.dev/hydrogen/passport/pkg/services"
 | 
			
		||||
	"github.com/gofiber/contrib/websocket"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func listenNotifications(c *websocket.Conn) {
 | 
			
		||||
	user := c.Locals("principal").(models.Account)
 | 
			
		||||
 | 
			
		||||
	// Push connection
 | 
			
		||||
	services.ClientRegister(user, c)
 | 
			
		||||
 | 
			
		||||
	// Event loop
 | 
			
		||||
	var err error
 | 
			
		||||
	for {
 | 
			
		||||
		if _, _, err = c.ReadMessage(); err != nil {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Pop connection
 | 
			
		||||
	services.ClientUnregister(user, c)
 | 
			
		||||
}
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/gofiber/contrib/websocket"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"git.solsynth.dev/hydrogen/passport/pkg"
 | 
			
		||||
	"git.solsynth.dev/hydrogen/passport/pkg/i18n"
 | 
			
		||||
	"git.solsynth.dev/hydrogen/passport/pkg/server/ui"
 | 
			
		||||
	"github.com/gofiber/contrib/websocket"
 | 
			
		||||
	"github.com/gofiber/fiber/v2"
 | 
			
		||||
	"github.com/gofiber/fiber/v2/middleware/cors"
 | 
			
		||||
	"github.com/gofiber/fiber/v2/middleware/favicon"
 | 
			
		||||
@@ -74,8 +74,6 @@ func NewServer() {
 | 
			
		||||
			notify.Post("/subscribe", authMiddleware, addNotifySubscriber)
 | 
			
		||||
			notify.Put("/batch/read", authMiddleware, markNotificationReadBatch)
 | 
			
		||||
			notify.Put("/:notificationId/read", authMiddleware, markNotificationRead)
 | 
			
		||||
 | 
			
		||||
			notify.Get("/listen", authMiddleware, websocket.New(listenNotifications))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		me := api.Group("/users/me").Name("Myself Operations")
 | 
			
		||||
@@ -136,6 +134,8 @@ func NewServer() {
 | 
			
		||||
		{
 | 
			
		||||
			developers.Post("/notify", notifyUser)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		api.Get("/ws", authMiddleware, websocket.New(listenWebsocket))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	A.Use(favicon.New(favicon.Config{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										77
									
								
								pkg/server/ws.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								pkg/server/ws.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"git.solsynth.dev/hydrogen/passport/pkg/models"
 | 
			
		||||
	"git.solsynth.dev/hydrogen/passport/pkg/services"
 | 
			
		||||
	"github.com/gofiber/contrib/websocket"
 | 
			
		||||
	jsoniter "github.com/json-iterator/go"
 | 
			
		||||
	"github.com/samber/lo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func listenWebsocket(c *websocket.Conn) {
 | 
			
		||||
	user := c.Locals("principal").(models.Account)
 | 
			
		||||
 | 
			
		||||
	// Push connection
 | 
			
		||||
	services.ClientRegister(user, c)
 | 
			
		||||
 | 
			
		||||
	// Event loop
 | 
			
		||||
	var task models.UnifiedCommand
 | 
			
		||||
 | 
			
		||||
	var messageType int
 | 
			
		||||
	var payload []byte
 | 
			
		||||
	var packet []byte
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		if messageType, packet, err = c.ReadMessage(); err != nil {
 | 
			
		||||
			break
 | 
			
		||||
		} else if err := jsoniter.Unmarshal(packet, &task); err != nil {
 | 
			
		||||
			_ = c.WriteMessage(messageType, models.UnifiedCommand{
 | 
			
		||||
				Action:  "error",
 | 
			
		||||
				Message: "unable to unmarshal your command, requires json request",
 | 
			
		||||
			}.Marshal())
 | 
			
		||||
			continue
 | 
			
		||||
		} else {
 | 
			
		||||
			payload, _ = jsoniter.Marshal(task.Payload)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var message *models.UnifiedCommand
 | 
			
		||||
		switch task.Action {
 | 
			
		||||
		case "kex.request":
 | 
			
		||||
			var req struct {
 | 
			
		||||
				RequestID string `json:"request_id"`
 | 
			
		||||
				KeypairID string `json:"keypair_id"`
 | 
			
		||||
				OwnerID   uint   `json:"owner_id"`
 | 
			
		||||
				Deadline  int64  `json:"deadline"`
 | 
			
		||||
			}
 | 
			
		||||
			_ = jsoniter.Unmarshal(payload, &req)
 | 
			
		||||
			if len(req.RequestID) <= 0 || len(req.KeypairID) <= 0 || req.OwnerID <= 0 {
 | 
			
		||||
				message = lo.ToPtr(models.UnifiedCommandFromError(fmt.Errorf("invalid request")))
 | 
			
		||||
			}
 | 
			
		||||
			services.KexRequest(c, req.RequestID, req.KeypairID, user.ID, req.Deadline)
 | 
			
		||||
		case "kex.provide":
 | 
			
		||||
			var req struct {
 | 
			
		||||
				RequestID string `json:"request_id"`
 | 
			
		||||
				KeypairID string `json:"keypair_id"`
 | 
			
		||||
				PublicKey []byte `json:"public_key"`
 | 
			
		||||
			}
 | 
			
		||||
			_ = jsoniter.Unmarshal(payload, &req)
 | 
			
		||||
			if len(req.RequestID) <= 0 || len(req.KeypairID) <= 0 {
 | 
			
		||||
				message = lo.ToPtr(models.UnifiedCommandFromError(fmt.Errorf("invalid request")))
 | 
			
		||||
			}
 | 
			
		||||
			services.KexProvide(user.ID, req.RequestID, req.KeypairID, payload)
 | 
			
		||||
		default:
 | 
			
		||||
			message = lo.ToPtr(models.UnifiedCommandFromError(fmt.Errorf("unknown action")))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if message != nil {
 | 
			
		||||
			if err = c.WriteMessage(messageType, message.Marshal()); err != nil {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Pop connection
 | 
			
		||||
	services.ClientUnregister(user, c)
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user