diff --git a/handle/yggdrasil/yggdrasil.go b/handle/yggdrasil/yggdrasil.go index 9e50d3a..3d7b402 100644 --- a/handle/yggdrasil/yggdrasil.go +++ b/handle/yggdrasil/yggdrasil.go @@ -2,30 +2,40 @@ package yggdrasil import ( "context" + "encoding/json" "io" "log/slog" + "net" "net/http" + "net/url" "github.com/go-playground/validator/v10" + "github.com/julienschmidt/httprouter" + "github.com/samber/lo" "github.com/xmdhs/authlib-skin/config" "github.com/xmdhs/authlib-skin/model/yggdrasil" + yggdrasilM "github.com/xmdhs/authlib-skin/model/yggdrasil" yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil" "github.com/xmdhs/authlib-skin/utils" ) +type PubRsaKey string + type Yggdrasil struct { logger *slog.Logger validate *validator.Validate yggdrasilService *yggdrasilS.Yggdrasil config config.Config + pubkey PubRsaKey } -func NewYggdrasil(logger *slog.Logger, validate *validator.Validate, yggdrasilService *yggdrasilS.Yggdrasil, config config.Config) *Yggdrasil { +func NewYggdrasil(logger *slog.Logger, validate *validator.Validate, yggdrasilService *yggdrasilS.Yggdrasil, config config.Config, pubkey PubRsaKey) *Yggdrasil { return &Yggdrasil{ logger: logger, validate: validate, yggdrasilService: yggdrasilService, config: config, + pubkey: pubkey, } } @@ -38,3 +48,32 @@ func getAnyModel[K any](ctx context.Context, w http.ResponseWriter, r io.Reader, } return a, true } + +func (y *Yggdrasil) YggdrasilRoot() httprouter.Handle { + return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + var host string + if y.config.TextureBaseUrl != "" { + u := lo.Must(url.Parse(y.config.TextureBaseUrl)) + host = u.Hostname() + } else { + host, _ = lo.TryOr[string](func() (string, error) { + h, _, err := net.SplitHostPort(r.Host) + return h, err + }, r.Host) + } + w.Write(lo.Must1(json.Marshal(yggdrasilM.Yggdrasil{ + Meta: yggdrasilM.YggdrasilMeta{ + ImplementationName: "authlib-skin", + ImplementationVersion: "0.0.1", + Links: yggdrasilM.YggdrasilMetaLinks{ + Homepage: "", + Register: "", + }, + ServerName: "test", + }, + SignaturePublickey: string(y.pubkey), + SkinDomains: []string{host}, + }))) + + } +} diff --git a/model/yggdrasil/model.go b/model/yggdrasil/model.go index d94f21b..f61023b 100644 --- a/model/yggdrasil/model.go +++ b/model/yggdrasil/model.go @@ -63,3 +63,21 @@ type Session struct { SelectedProfile string `json:"selectedProfile" validate:"required,uuid"` ServerID string `json:"serverId"` } + +type Yggdrasil struct { + Meta YggdrasilMeta `json:"meta"` + SignaturePublickey string `json:"signaturePublickey"` + SkinDomains []string `json:"skinDomains"` +} + +type YggdrasilMeta struct { + ImplementationName string `json:"implementationName"` + ImplementationVersion string `json:"implementationVersion"` + Links YggdrasilMetaLinks `json:"links"` + ServerName string `json:"serverName"` +} + +type YggdrasilMetaLinks struct { + Homepage string `json:"homepage"` + Register string `json:"register"` +} diff --git a/server/provide.go b/server/provide.go index 439c1fa..e693cfc 100644 --- a/server/provide.go +++ b/server/provide.go @@ -16,6 +16,7 @@ import ( "github.com/xmdhs/authlib-skin/db/cache" "github.com/xmdhs/authlib-skin/db/ent" "github.com/xmdhs/authlib-skin/db/ent/migrate" + "github.com/xmdhs/authlib-skin/handle/yggdrasil" "github.com/xmdhs/authlib-skin/utils/sign" ) @@ -87,4 +88,12 @@ func ProvidePriKey(c config.Config) (*rsa.PrivateKey, error) { return a.GetKey(), nil } -var Set = wire.NewSet(ProvideSlog, ProvideDB, ProvideEnt, ProvideValidate, ProvideCache, ProvidePriKey) +func ProvidePubKey(pri *rsa.PrivateKey) (yggdrasil.PubRsaKey, error) { + s, err := sign.NewAuthlibSignWithKey(pri).GetPubKey() + if err != nil { + return "", fmt.Errorf("ProvidePubKey: %w", err) + } + return yggdrasil.PubRsaKey(s), nil +} + +var Set = wire.NewSet(ProvideSlog, ProvideDB, ProvideEnt, ProvideValidate, ProvideCache, ProvidePriKey, ProvidePubKey) diff --git a/server/route/route.go b/server/route/route.go index 02e86b1..1644b41 100644 --- a/server/route/route.go +++ b/server/route/route.go @@ -2,7 +2,6 @@ package route import ( "fmt" - "net/http" "github.com/julienschmidt/httprouter" "github.com/xmdhs/authlib-skin/handle" @@ -38,18 +37,7 @@ func newYggdrasil(r *httprouter.Router, handelY yggdrasil.Yggdrasil) error { r.POST("/api/yggdrasil/sessionserver/session/minecraft/join", warpHJSON(handelY.SessionJoin())) r.GET("/api/yggdrasil/sessionserver/session/minecraft/hasJoined", warpHJSON(handelY.SessionJoin())) - r.GET("/api/yggdrasil", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - w.Write([]byte(`{ - "meta": { - "serverName": "test", - "implementationName": "test", - "implementationVersion": "999.999.999" - }, - "skinDomains": [ - ], - "signaturePublickey": "123" - }`)) - }) + r.GET("/api/yggdrasil", warpHJSON(handelY.YggdrasilRoot())) return nil } diff --git a/server/wire_gen.go b/server/wire_gen.go index bc5c2d5..bd30c2e 100644 --- a/server/wire_gen.go +++ b/server/wire_gen.go @@ -44,7 +44,13 @@ func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func() return nil, nil, err } yggdrasilYggdrasil := yggdrasil.NewYggdrasil(client, cache, c, privateKey) - yggdrasil3 := yggdrasil2.NewYggdrasil(logger, validate, yggdrasilYggdrasil, c) + pubRsaKey, err := ProvidePubKey(privateKey) + if err != nil { + cleanup2() + cleanup() + return nil, nil, err + } + yggdrasil3 := yggdrasil2.NewYggdrasil(logger, validate, yggdrasilYggdrasil, c, pubRsaKey) webService := service.NewWebService(c, client) handel := handle.NewHandel(webService, validate, c, logger) router, err := route.NewRoute(yggdrasil3, handel)