package hwsauth import ( "net/http" "time" "git.haelnorr.com/h/golib/hws" "github.com/pkg/errors" ) // LoginReq returns a middleware that requires the user to be authenticated. // If the user is not authenticated, it returns a 401 Unauthorized error page. // // Example: // // protectedHandler := auth.LoginReq(http.HandlerFunc(dashboardHandler)) // server.AddRoute("GET", "/dashboard", protectedHandler) func (auth *Authenticator[T, TX]) LoginReq(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, ok := getAuthorizedModel[T](r.Context()) if !ok { auth.server.ThrowError(w, r, hws.HWSError{ Error: errors.New("Login required"), Message: "Please login to view this page", StatusCode: http.StatusUnauthorized, RenderErrorPage: true, }) return } next.ServeHTTP(w, r) }) } // LogoutReq returns a middleware that redirects authenticated users to the landing page. // Use this for login and registration pages to prevent logged-in users from accessing them. // // Example: // // loginPageHandler := auth.LogoutReq(http.HandlerFunc(showLoginPage)) // server.AddRoute("GET", "/login", loginPageHandler) func (auth *Authenticator[T, TX]) LogoutReq(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, ok := getAuthorizedModel[T](r.Context()) if ok { http.Redirect(w, r, auth.LandingPage, http.StatusFound) return } next.ServeHTTP(w, r) }) } // FreshReq returns a middleware that requires a fresh authentication token. // If the token is not fresh (recently issued), it returns a 444 status code. // Use this for sensitive operations like password changes or account deletions. // // Example: // // changePasswordHandler := auth.FreshReq(http.HandlerFunc(handlePasswordChange)) // server.AddRoute("POST", "/change-password", changePasswordHandler) // // The 444 status code can be used by the client to prompt for re-authentication. func (auth *Authenticator[T, TX]) FreshReq(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { model, ok := getAuthorizedModel[T](r.Context()) if !ok { auth.server.ThrowError(w, r, hws.HWSError{ Error: errors.New("Login required"), Message: "Please login to view this page", StatusCode: http.StatusUnauthorized, RenderErrorPage: true, }) return } isFresh := time.Now().Before(time.Unix(model.fresh, 0)) if !isFresh { w.WriteHeader(444) return } next.ServeHTTP(w, r) }) }