daddy/internal/route/mount.go

112 lines
2.7 KiB
Go

package route
import (
"context"
"net/http"
"path"
"time"
"github.com/99designs/gqlgen/graphql"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"forge.cadoles.com/Cadoles/daddy/internal/config"
"forge.cadoles.com/Cadoles/daddy/internal/graph"
"forge.cadoles.com/Cadoles/daddy/internal/graph/generated"
"forge.cadoles.com/Cadoles/daddy/internal/session"
oidc "forge.cadoles.com/wpetit/goweb-oidc"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/99designs/gqlgen/graphql/handler/transport"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/gorilla/websocket"
"github.com/go-chi/chi"
"github.com/rs/cors"
"gitlab.com/wpetit/goweb/static"
)
func Mount(r *chi.Mux, config *config.Config) error {
r.With(oidc.HandleCallback).Get("/oauth2/callback", handleLoginCallback)
r.Get("/logout", handleLogout)
r.Get("/login", handleLogin)
r.Get("/logout/redirect", handleLogoutRedirect)
r.Route("/api", func(r chi.Router) {
r.Use(cors.New(cors.Options{
AllowedOrigins: config.HTTP.CORS.AllowedOrigins,
AllowCredentials: config.HTTP.CORS.AllowCredentials,
Debug: config.Debug,
}).Handler)
r.Use(session.UserEmailMiddleware)
gqlConfig := generated.Config{
Resolvers: &graph.Resolver{},
}
gql := handler.New(
generated.NewExecutableSchema(gqlConfig),
)
gql.SetRecoverFunc(func(ctx context.Context, err interface{}) error {
// Dispatch error to Sentry
if realErr, ok := err.(error); ok {
sentry.CaptureException(realErr)
}
if strErr, ok := err.(string); ok {
sentry.CaptureException(errors.New(strErr))
}
return graphql.DefaultRecover(ctx, err)
})
gql.AddTransport(transport.POST{})
gql.AddTransport(&transport.Websocket{
KeepAlivePingInterval: 10 * time.Second,
Upgrader: websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
// TODO Check WS connection origin
return true
},
ReadBufferSize: 1024,
WriteBufferSize: 1024,
},
})
if config.Debug {
gql.Use(extension.Introspection{})
r.Get("/v1/playground", playground.Handler("GraphQL playground", "/api/v1/graphql"))
}
r.Handle("/v1/graphql", gql)
})
clientIndex := path.Join(config.HTTP.PublicDir, "index.html")
serveClientIndex := func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, clientIndex)
}
// List of paths handled directly by the client
clientRoutes := []string{
"/workgroups/*",
"/profile",
"/dashboard",
"/decisions/*",
"/unauthorized",
"/conference",
}
for _, cr := range clientRoutes {
r.Get(cr, serveClientIndex)
}
// Serve static files
notFoundHandler := r.NotFoundHandler()
r.Get("/*", static.Dir(config.HTTP.PublicDir, "", notFoundHandler))
return nil
}