2024-09-27 14:53:22 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
2024-11-06 15:58:57 +00:00
|
|
|
"fmt"
|
2024-09-27 14:53:22 +00:00
|
|
|
"io/fs"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/mstarongithub/passkey"
|
|
|
|
"github.com/rs/zerolog/log"
|
2024-10-15 18:41:23 +00:00
|
|
|
"gitlab.com/mstarongitlab/goutils/other"
|
2024-09-27 14:53:22 +00:00
|
|
|
"gitlab.com/mstarongitlab/linstrom/storage"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Server struct {
|
|
|
|
store *storage.Storage
|
|
|
|
router http.Handler
|
2024-11-15 15:14:29 +00:00
|
|
|
server *http.Server
|
2024-09-27 14:53:22 +00:00
|
|
|
}
|
|
|
|
|
2024-11-06 15:58:57 +00:00
|
|
|
func NewServer(
|
|
|
|
store *storage.Storage,
|
|
|
|
pkey *passkey.Passkey,
|
|
|
|
reactiveFS, staticFS fs.FS,
|
|
|
|
placeholderFile *string,
|
|
|
|
) *Server {
|
|
|
|
handler := buildRootHandler(pkey, reactiveFS, staticFS, placeholderFile)
|
2024-10-15 14:16:18 +00:00
|
|
|
handler = ChainMiddlewares(handler, LoggingMiddleware, ContextValsMiddleware(map[any]any{
|
|
|
|
ContextKeyStorage: store,
|
|
|
|
}))
|
2024-11-15 15:14:29 +00:00
|
|
|
|
|
|
|
server := http.Server{
|
|
|
|
Handler: handler,
|
|
|
|
}
|
2024-09-27 14:53:22 +00:00
|
|
|
return &Server{
|
|
|
|
store: store,
|
|
|
|
router: handler,
|
2024-11-15 15:14:29 +00:00
|
|
|
server: &server,
|
2024-09-27 14:53:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-06 15:58:57 +00:00
|
|
|
func buildRootHandler(
|
|
|
|
pkey *passkey.Passkey,
|
|
|
|
reactiveFS, staticFS fs.FS,
|
|
|
|
placeholderFile *string,
|
|
|
|
) http.Handler {
|
2024-09-27 14:53:22 +00:00
|
|
|
mux := http.NewServeMux()
|
2024-10-20 18:05:13 +00:00
|
|
|
mux.Handle(
|
|
|
|
"/webauthn/",
|
|
|
|
http.StripPrefix(
|
|
|
|
"/webauthn",
|
|
|
|
forceCorrectPasskeyAuthFlowMiddleware(buildPasskeyAuthRouter(pkey)),
|
|
|
|
),
|
|
|
|
)
|
2024-10-15 14:16:18 +00:00
|
|
|
mux.Handle("/", setupFrontendRouter(reactiveFS, staticFS))
|
2024-09-27 14:53:22 +00:00
|
|
|
mux.Handle("/pk/", http.StripPrefix("/pk", http.FileServer(http.Dir("pk-auth"))))
|
2024-10-15 19:26:48 +00:00
|
|
|
mux.HandleFunc("/alive", isAliveHandler)
|
2024-11-04 15:25:39 +00:00
|
|
|
mux.Handle("/api/", http.StripPrefix("/api", checkSessionMiddleware(setupApiRouter())))
|
2024-10-15 19:26:48 +00:00
|
|
|
|
2024-10-26 09:42:51 +00:00
|
|
|
mux.Handle(
|
|
|
|
"/profiling/",
|
|
|
|
http.StripPrefix("/profiling", profilingAuthenticationMiddleware(setupProfilingHandler())),
|
|
|
|
)
|
|
|
|
// temporary until proper route structure exists
|
2024-10-15 14:16:18 +00:00
|
|
|
mux.Handle(
|
|
|
|
"/authonly/",
|
|
|
|
pkey.Auth(
|
|
|
|
ContextKeyPasskeyUsername,
|
|
|
|
nil,
|
2024-10-15 18:41:23 +00:00
|
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
other.HttpErr(
|
|
|
|
w,
|
|
|
|
HttpErrIdNotAuthenticated,
|
|
|
|
"Not authenticated",
|
|
|
|
http.StatusUnauthorized,
|
|
|
|
)
|
|
|
|
},
|
2024-10-15 14:16:18 +00:00
|
|
|
)(ChainMiddlewares(setupTestEndpoints(), passkeyIdToAccountIdTransformerMiddleware)),
|
|
|
|
)
|
2024-09-27 14:53:22 +00:00
|
|
|
|
2024-11-06 15:58:57 +00:00
|
|
|
mux.HandleFunc("/placeholder-file", func(w http.ResponseWriter, r *http.Request) {
|
2024-11-18 11:18:57 +00:00
|
|
|
fmt.Fprint(w, *placeholderFile)
|
2024-11-06 15:58:57 +00:00
|
|
|
})
|
|
|
|
|
2024-09-27 14:53:22 +00:00
|
|
|
return mux
|
|
|
|
}
|
|
|
|
|
2024-10-20 18:05:13 +00:00
|
|
|
func buildPasskeyAuthRouter(pkey *passkey.Passkey) http.Handler {
|
|
|
|
router := http.NewServeMux()
|
|
|
|
pkey.MountRoutes(router, "/")
|
|
|
|
return router
|
|
|
|
}
|
|
|
|
|
2024-10-15 14:16:18 +00:00
|
|
|
func (s *Server) Start(addr string) error {
|
2024-09-27 14:53:22 +00:00
|
|
|
log.Info().Str("addr", addr).Msg("Starting server")
|
2024-11-15 15:14:29 +00:00
|
|
|
s.server.Addr = addr
|
|
|
|
return s.server.ListenAndServe()
|
2024-09-27 14:53:22 +00:00
|
|
|
}
|