package queryapi import ( "context" "fmt" "net/http" "strings" "github.com/labstack/echo/v4" "github.com/lestrrat-go/jwx/v2/jwt" ) // Constants for route paths const ( LOGIN_CALLBACK_PATH = "/login-callback" ) // endpointsList keeps track of registered endpoints // This list should be kept in sync with actual route registrations var endpointsList = []string{ // Auth Service Endpoints "/login", LOGIN_CALLBACK_PATH, "/logout", "/home", // Client Service Endpoints "/client", // Query API Endpoints "/query", // Document Service Endpoints "/document", // Export Service Endpoints "/export", } // homeHandler renders a simple HTML page with links to all endpoints // and displays authentication status based on JWT token func HomeHandler(c echo.Context) error { var linksHTML string baseURL := "http://localhost:8080" // Create list items for each endpoint for _, endpoint := range endpointsList { // Skip endpoints with path parameters for direct linking if strings.Contains(endpoint, ":") { displayPath := strings.Replace(endpoint, ":id", "{id}", -1) linksHTML += fmt.Sprintf("
  • %s (requires parameter)
  • \n", displayPath) } else { linksHTML += fmt.Sprintf("
  • %s
  • \n", baseURL, endpoint, endpoint) } } // Check if user is authenticated by looking for token in cookie tokenCookie, err := c.Cookie("auth_token") isAuthenticated := (err == nil && tokenCookie.Value != "") // Variables for user info var subject string // If authenticated, try to decode the JWT token to get user info if isAuthenticated { // Use the same JWT parsing logic as the middleware to handle formatted tokens tokenString := tokenCookie.Value // Handle RFC-compliant unsecured JWTs that may have only 2 parts (header.payload.) parts := strings.Split(tokenString, ".") if len(parts) == 2 { // Add empty signature part to make it parseable by the JWT library tokenString = tokenString + "." } // Parse token without verification (just for display purposes) token, err := jwt.Parse( []byte(tokenString), jwt.WithVerify(false), // Skip signature verification jwt.WithValidate(false), // Skip expiration and other validations ) if err != nil { subject = "JWT parsing failed: " + err.Error() } else if token != nil { claims, err := token.AsMap(context.Background()) if err != nil { subject = "Claims extraction failed: " + err.Error() } else { if sub, ok := claims["sub"].(string); ok { subject = sub } else { subject = "Subject claim not found or invalid type" } } } else { subject = "Token is nil" } } // Create authentication status section var authStatusHTML string if isAuthenticated { authStatusHTML = fmt.Sprintf(`

    Authentication Status: Authenticated

    Subject: %s

    Logout

    `, subject) } else { authStatusHTML = `

    Authentication Status: Not Authenticated

    You are not currently logged in.

    ` } // Create the complete HTML page html := fmt.Sprintf(` Doczy Home

    Doczy Home

    %s

    Available Endpoints

    Note: This is a debugging page. Some endpoints require authentication or specific permissions.

    `, authStatusHTML, linksHTML) return c.HTML(http.StatusOK, html) }