server.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package main
  2. import (
  3. "context"
  4. "log"
  5. "net/http"
  6. "os"
  7. "github.com/99designs/gqlgen/graphql/handler"
  8. "github.com/99designs/gqlgen/graphql/handler/extension"
  9. "github.com/99designs/gqlgen/graphql/handler/lru"
  10. "github.com/99designs/gqlgen/graphql/handler/transport"
  11. "github.com/99designs/gqlgen/graphql/playground"
  12. "github.com/vektah/gqlparser/v2/ast"
  13. "gogs.dmsc.dev/arp/auth"
  14. "gogs.dmsc.dev/arp/graph"
  15. "gogs.dmsc.dev/arp/models"
  16. "gorm.io/driver/sqlite"
  17. "gorm.io/gorm"
  18. )
  19. const defaultPort = "8080"
  20. func main() {
  21. port := os.Getenv("PORT")
  22. if port == "" {
  23. port = defaultPort
  24. }
  25. // Initialize database
  26. db, err := gorm.Open(sqlite.Open("arp.db"), &gorm.Config{})
  27. if err != nil {
  28. log.Fatal("failed to connect database:", err)
  29. }
  30. // Run auto-migration for all models
  31. err = db.AutoMigrate(&models.User{}, &models.Role{}, &models.Permission{}, &models.Service{}, &models.Task{}, &models.TaskStatus{}, &models.Channel{}, &models.Message{}, &models.Note{})
  32. if err != nil {
  33. log.Fatal("failed to migrate database:", err)
  34. }
  35. // Create resolver with DB instance using NewResolver for pub/sub support
  36. resolver := graph.NewResolver(db)
  37. srv := handler.New(graph.NewExecutableSchema(graph.Config{Resolvers: resolver}))
  38. srv.AddTransport(transport.Options{})
  39. srv.AddTransport(transport.GET{})
  40. srv.AddTransport(transport.POST{})
  41. srv.AddTransport(&transport.Websocket{
  42. // Authenticate WebSocket connections
  43. InitFunc: func(ctx context.Context, initPayload transport.InitPayload) (context.Context, *transport.InitPayload, error) {
  44. // Get token from connection params
  45. token, ok := initPayload["Authorization"].(string)
  46. if !ok {
  47. return ctx, nil, nil
  48. }
  49. // Validate token and add user to context
  50. claims, err := auth.ValidateToken(token)
  51. if err != nil {
  52. return ctx, nil, nil
  53. }
  54. // Convert Claims to UserContext
  55. userCtx := &auth.UserContext{
  56. ID: claims.UserID,
  57. Email: claims.Email,
  58. Roles: claims.Roles,
  59. Permissions: claims.Permissions,
  60. }
  61. ctx = auth.WithUser(ctx, userCtx)
  62. return ctx, nil, nil
  63. },
  64. })
  65. srv.SetQueryCache(lru.New[*ast.QueryDocument](1000))
  66. srv.Use(extension.Introspection{})
  67. srv.Use(extension.AutomaticPersistedQuery{
  68. Cache: lru.New[string](100),
  69. })
  70. http.Handle("/", playground.Handler("GraphQL playground", "/query"))
  71. http.Handle("/query", auth.AuthMiddleware(srv))
  72. log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
  73. log.Fatal(http.ListenAndServe(":"+port, nil))
  74. }